繁体   English   中英

令人困惑的Python语句行为

[英]Confusing behavior of Python for statement

我有以下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? 打印语句不在if语句内!

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

您要从列表( x.remove )删除项目,同时对其进行迭代( for number in x )。

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

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

例如:

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

为了清楚起见,添加一些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]

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

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

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

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

之所以没有打印一些数字,是因为当您循环并删除它们时,这些值正在改变位置。 当您删除1 ,您可以想象所有值都被移动了一个位置,迭代器指向2以前的位置,但是现在该值是3 ,因此永远不会打印2 对于其余的值,这一点还在继续。

正如Mark Rushakoff提到的那样,在迭代过程中不应修改某些内容。 for number in xfor number in x[:]更改for number in x for number in x[:] ,尽管如此,它仍然可以正常工作。 在这种情况下,您要遍历一个副本。

不要修改您要遍历的列表。 其他建议复制列表或收集要删除的新列表。 相反,请收集您想要保留的物品。 这比复制列表并从未迭代的副本中删除要快,并且比收集要删除的对象然后再删除它们要快。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM