令人困惑的Python语句行为

时间:2013-04-14 22:18:39

标签: python windows if-statement for-loop

我有以下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 ++

6 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

使用索引迭代列表,但删除元素时会跳过一些索引。

E.g:

[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)

答案 2 :(得分: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]

答案 3 :(得分:1)

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

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

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

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

不打印某些数字的原因是当您循环并删除它们时,值会更改位置。当您移除1时,您可以想象所有值都移动了一个位置,迭代器指向2曾经的位置,但现在值为3,所以永远不会打印2。其余的价值观也在继续。

答案 4 :(得分:1)

正如Mark Rushakoff所提到的那样,在迭代它时你不应该修改某些东西。将您的for number in x更改为for number in x[:],但它会按预期运行。在这种情况下,您将迭代副本。

答案 5 :(得分:1)

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

    evens = []
    for number in x:
        if number%2 == 0:
            evens += [number]
    print(evens)