簡體   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