2013-05-29 198 views
104

考慮:Python列表迭代器的行爲和未來(迭代器)

>>> lst = iter([1,2,3]) 
>>> next(lst) 
1 
>>> next(lst) 
2 

因此,推進迭代器,符合市場預期,通過突變相同的對象處理。

在這情況下,我希望:

a = iter(list(range(10))) 
for i in a: 
    print(i) 
    next(a) 

跳過每第二個元素:調用next應提前迭代一次,然後通過循環進行的隱式調用應提前它第二次 - 並且第二次調用的結果將被分配到i

它沒有。該循環在列表中打印全部的項目,而不跳過任何項目。

我的第一個想法是,這可能會發生,因爲循環調用iter它傳遞的內容,這可能會給一個獨立的迭代器 - 情況並非如此,因爲我們有iter(a) is a

那麼,爲什麼next在這種情況下似乎沒有推進迭代器?

回答

137

你看到的是解釋回顯的除了next()i的返回值被打印在每個迭代:

>>> a = iter(list(range(10))) 
>>> for i in a: 
... print(i) 
... next(a) 
... 
0 
1 
2 
3 
4 
5 
6 
7 
8 
9 

所以0print(i)輸出,1回報從next()得到的值,由交互式解釋器迴應等等。只有5次迭代,每次迭代導致2行被寫入終端。

如果分配的next()事物的輸出按預期工作:

>>> a = iter(list(range(10))) 
>>> for i in a: 
... print(i) 
... _ = next(a) 
... 
0 
2 
4 
6 
8 

或打印額外信息從交互式解釋回聲區分print()輸出:

>>> a = iter(list(range(10))) 
>>> for i in a: 
... print('Printing: {}'.format(i)) 
... next(a) 
... 
Printing: 0 
1 
Printing: 2 
3 
Printing: 4 
5 
Printing: 6 
7 
Printing: 8 
9 

換句話說,next()按預期工作,但是因爲它會從迭代器返回下一個值,並由交互式解釋器響應,您將被導入相信循環以某種方式具有自己的迭代器複製。

+8

我不知道從解釋這種行爲。我很高興我發現,在解決一些真正的問題的同時,在浪費了大量時間之前,我還想知道它。 – brandizzi

+3

... \ *死亡*。最糟糕的是,我可以記得在一週前向某人提及這種解釋行爲。 – lvc

+0

有趣。我在a:next(a)中嘗試了我;打印我並認爲我會跳到1並打印1,3,5,7,9。但仍然是0,2,4,6,8。爲什麼? – user2290820

2

您的Python /計算機出現問題。

a = iter(list(range(10))) 
for i in a: 
    print(i) 
    next(a) 

>>> 
0 
2 
4 
6 
8 

像預期的那樣工作。

使用Python 2.7和Python 3+進行測試。正常工作在這兩個

+5

,我得到了相同的結果@lvc(僅在IDLE然而,當作爲腳本我得到這個執行)) – jamylak

+3

@Inbar Rose僅當您以腳本運行時纔有效。 – thecoder16

+0

它是通過交互式shell放置代碼的行爲。如果函數返回而不使用值,解釋將打印到shell作爲調試輸出 – Reishin

10

發生了什麼事是next(a)返回a的下一個值,該值將打印到控制檯,因爲它不受影響。

你可以做什麼是影響一個變量,這個值:

>>> a = iter(list(range(10))) 
>>> for i in a: 
... print(i) 
... b=next(a) 
... 
0 
2 
4 
6 
8 
6

我覺得現有的答案有點混亂,因爲他們只間接地表明瞭代碼示例基本神祕的事: * 「打印我」和「下一個(a)」導致他們的結果被打印。

因爲他們印刷交替原始序列的元素,這是意想不到的是,「未來(一)」語句是印刷,它看起來好像「打印我」語句打印所有值。

有鑑於此,將變量「next(a)」的結果賦值給一個變量禁止打印其結果,這樣就可以打印出「i」循環變量的替代值。同樣,使「印刷」聲明發出更明確的內容也可以消除歧義。

(因爲這個問題的答案是具有評價爲塊的示例代碼,使得解釋器不是「下一個的(a)」。報告了中間值的一種現有答案反駁了其他)一般來說,在回答問題時出乎意料的是,一旦你知道答案,就會明確表明什麼是顯而易見的。它可能難以捉摸。同樣,一旦你瞭解他們就會批評答案。這很有趣......

1

它的行爲你想,如果作爲函數調用的方式:

>>> def test(): 
...  a = iter(list(range(10))) 
...  for i in a: 
...   print(i) 
...   next(a) 
... 
>>> test() 
0 
2 
4 
6 
8