当我在python中使用'for'时丢失了一个元素,发生了什么?

时间:2014-03-15 12:08:09

标签: python

我写了一个python程序如下:

from os import listdir 
def getfilename():
    namelist=listdir(".")
    print namelist
    for name in namelist:
        print name
        if 'lp' in name:
            namelist.remove(name)
    return namelist

当我在命令行上运行它并打印返回值时,结果是:

['all_test1.list', 'all_test2.list', 'lp.py', 'lp.pyc', 'lp.test', 'straightrnd_test1.list', 'straightrnd_test2.list', 'straightrnd_train.list']
all_test1.list
all_test2.list
lp.py
lp.test
straightrnd_test2.list
straightrnd_train.list
['all_test1.list', 'all_test2.list', 'lp.pyc', 'straightrnd_test1.list', 'straightrnd_test2.list', 'straightrnd_train.list']  

文件'lp.pyc'在for循环中丢失,所以返回值包含它,我想从列表中删除它,我该怎么办?为什么元素在for循环中丢失了?

2 个答案:

答案 0 :(得分:2)

您正在改变您正在迭代的列表。使用列表推导:

newlist = [x for x in namelist if 'lp' not in x]

答案 1 :(得分:1)

这个question很好地解决了这个问题,但简而言之:

即使你没有通过元素的索引明确地循环遍历列表,Python也会在内部对你进行排序。

这就好像你写了类似的东西:

l = listdir(".")
while i < len(l):
    name = l[i]
    if 'lp' in name:
        l.remove(name)
        # Now evaluating l[i] yields another element, even though i was not incremented !

    i = i + 1

因此,当您在迭代期间删除元素时,它会将循环指针移动一次太多,因此您正在观察问题。

请注意,在您的情况下,您可以写:

from os import listdir 

def getfilename():
    return [x for x in listdir(".") if not 'lp' in x]

即使名称getfilename有点奇怪,因为它实际上返回了一个列表......但这是另一个问题。