1

我有以下python代码:

x = range(0,10)
print x

for number in x: 
    print(number)
    if number%2<> 0: 
        x.remove(number)

print x

奇怪的是,输出是这样的:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
3
5
7
9
[0, 2, 4, 6, 8]

第一行和最后一行是对的,但是为什么2、4、6、8没有打印出来呢?print 语句不在 if 语句中!

我在 Windows 7 上使用 python(x,y)。另外,我是 Python 新手...我习惯 C++

4

6 回答 6

2

您在x.remove迭代列表 ( ) 时从列表 ( ) 中删除项目for number in x

for-in单独维护一个索引,这就是修改列表会产生意外行为的原因。

于 2013-04-14T22:21:31.997 回答
2

该列表使用其索引进行迭代,但是当您删除元素时,您会跳过一些索引。

例如:

[0,1,2,...] # (iterator is at second - print 1)

消除

[0,2,3,...] # (iterator is still at second)

迭代器前进

[0,2,3,...] # (iterator is at third - print 3)
于 2013-04-14T22:24:24.530 回答
2

为了清楚起见,添加一些print语句:

x = range(10)

for index, number in enumerate(x):
    print "x is      ", x
    print "element is", number
    print "index is  ", index
    print

    if number % 2 == 0: 
        x.remove(number)

和输出:

x is       [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
element is 0
index is   0

x is       [1, 2, 3, 4, 5, 6, 7, 8, 9]
element is 2
index is   1

x is       [1, 3, 4, 5, 6, 7, 8, 9]
element is 4
index is   2

x is       [1, 3, 5, 6, 7, 8, 9]
element is 6
index is   3

x is       [1, 3, 5, 7, 8, 9]
element is 8
index is   4

如您所见,即使您从列表中删除元素,它也会index继续上升。1这就是导致循环跳过元素的原因。

正如其他人指出的那样,遍历列表并从中删除元素并不是一个好主意。而是遍历一个副本:

for number in x[:]:

或者:

for number in list(x):

更好的是,使用列表理解创建一个新列表:

[number for number in x if number % 2 == 0]
于 2013-04-14T22:29:26.333 回答
1

基本上,当您在删除的同时迭代某些内容时,您可能会有奇怪的行为。发生的情况是您跳过了一些值,因为它们被转移到您已经迭代过的索引。

做你想做的事(过滤掉一些项目)的更好方法是使用列表理解,例如:

[x for x in range(10) if x%2==0]

您可以简单地使用该range步骤仅创建偶数,但上述解决方案可让您在任何条件下过滤掉。

未打印某些数字的原因是,当您循环并删除它们时,这些值正在改变位置。当你删除 时1,你可以想象所有的值都被移动了一个位置,迭代器指向了以前的位置2,但是现在那里的值是3,所以2永远不会打印。其余的值也是如此。

于 2013-04-14T22:23:10.750 回答
1

正如 Mark Rushakoff 所提到的,你不应该在迭代时修改它。不过,将您的更改for number in xfor number in x[:],它将按您的预期工作。在这种情况下,您正在迭代副本。

于 2013-04-14T22:23:56.127 回答
1

不要修改您正在迭代的列表。其他人建议复制列表或收集要删除的新列表。相反,收集你留下的那些。这比复制列表并从未迭代的副本中删除要快,并且比收集要删除的列表然后删除它们要快。

    evens = []
    for number in x:
        if number%2 == 0:
            evens += [number]
    print(evens)
于 2013-04-14T23:11:20.813 回答