首页 > 代码库 > 从Python列表Remove操作的一个小问题说开去

从Python列表Remove操作的一个小问题说开去

  一.问题 :

       前两天因工作需要,写了一个Python小程序, 将某目录下所有长度小于19的文件夹过滤掉,例如这个这个目录:

      

   

        过滤完成后,只需要剩余“2014_11_03-12-11-23”,“2014_11_04-13-11-26”这两个文件夹即可。

       

       程序如下:

cwdlist = os.listdir("E:\Python")
for i in cwdlist:
    if len(i) <> 19:
         cwdlist.remove(i)
print cwdlist
    

      但返回结果却事与愿违,结果如下:

    

    为什么“237”这个文件夹没有被删掉呢?

    在网上查找了一下,原来问题出在List操作的Remove方法上,Remove方法删除第一次出现的该元素。

    也就是说它会按照元素进行查询,遇到的第一个匹配的就将其删除。更为重要的是:删除的元素位置会被后面的元素填补上。


   也就是说,程序在删除”236“后,这个位置被后面的”237“给补上了,这个时刻,

    列表的下标已经移到了最后一个元素”237“的位置,删除”237“后,整个循环结束。

 

 二.解决方法:

        1.最简单的方法,再复制一份列表来操作:

cwdlist = os.listdir("E:\Python")
cwdlist2 = list(cwdlist)
for i in cwdlist2:
    if len(i) <> 19:
         cwdlist.remove(i)
print cwdlist

     

       2.使用filter函数:

cwdlist = os.listdir("E:\Python")
def f(x): return len(x) == 19
print filter(f,cwdlist)

      

      3.再简洁一点的写法,使用lambda表达式:

cwdlist = os.listdir("E:\Python")
f=lambda x:len(x) == 19
print filter(f,cwdlist)
   或者
cwdlist = os.listdir("E:\Python")
print filter(lambda x:len(x) == 19,cwdlist)


      4.更为pythonic的方法,使用列表推导式:

cwdlist = os.listdir("E:\Python")
print [i for i in cwdlist if len(i) == 19]


   其实,这几种方法的本质都是相同的,都是新建了一份列表。

从Python列表Remove操作的一个小问题说开去