2014-01-24 72 views

回答

7

想象一下,你想寫一個遍歷任何類型的迭代代碼。通常情況下你只寫了for陳述或理解,但讓我們而是明確做什麼for在幕後做,以使事情變得更加明顯:

i = iter(iterable) 
while True: 
    try: 
     val = next(i) 
    except StopIteration: 
     break 
    else: 
     do_stuff(val) 

如果你不這樣做第一線,你的代碼韓元不適用於列表,字符串,元組或其他任何東西,但迭代器。

但是,如果你做的第一線,很好,iter(iterable)最好返回一個迭代器,或者你的代碼不會與迭代工作。


你可能想知道爲什麼iter不能沒有這個做正確的事情?畢竟,這確實因爲有__len____getitem__但沒有__iter__對象時有它的魔力來創建一個迭代器,那麼爲什麼不能也有魔法剛剛返回它的參數,如果它有一個__next__但沒有__iter__?這是一個語言設計問題,但一般來說,Python試圖儘可能少用魔法。使迭代不順序的魔力是必要的,因爲在將迭代協議添加到語言之前,這樣的序列存在(在廣泛的第三方代碼中),並且爲了簡化事情的小好處而去除太難了。

+0

@delnan:答案已經說:「你平時只是用'for'語句(或理解)......這確實在幕後的代碼。」這是否需要更清楚? – abarnert

+1

我想我只是錯過了那部分。這可能表明它需要更多突出顯示,或者我需要仔細閱讀:-) – delnan

+0

@delnan:好的,新版本更好嗎? – abarnert

0

這樣的for循環和其他需要與iterables一起工作的代碼可以無條件地調用iter來迭代它們,而不是分別處理迭代器和其他迭代器。特別是,非迭代器可能合理地有一個名爲next的方法,我們希望能夠將它們與迭代器區分開來。

+0

這不是因爲非迭代器可能有一個名爲'next'的方法。 (當然這也許就是爲什麼'next'被重命名爲'__next__')。 – abarnert

1

for 0123應該使用迭代器,因此for i in something:會自動調用iter(something)來獲取迭代器並遍歷所述迭代器。現在,如果迭代器並沒有太多可迭代(即沒有定義__iter__),你不能使用for循環迭代器,即:

items = [1, 2, 3] 
# this would work 
for item in items: pass 
# this wouldn't 
it = iter(items) 
for item in it: pass 

因此,迭代器應該是iterables了。另一種方式,「以某種方式檢測」迭代器,而不是調用iter對他們來說,是hacky和脆弱的(你會如何決定?)。

+0

你決定這樣做的方式 - 就像python-ideas每年提出一次或兩次提議(並且被拒絕)一樣簡單:如果'在執行回退到基於索引的迭代之前,首先檢查是否存在「i .__ next__」,如果是,則返回「i」。 – abarnert

+0

@abarnert難道不是因爲缺乏一個更好的措辭,「hacky and fragile」? ;-) – delnan

+0

這個改變將會是'iter'實現中幾行簡單明顯的代碼。多人編寫了一些補丁,這些補丁在第一次嘗試時就能夠正常工作並通過完整的測試套件,這意味着它不是那麼脆弱。真正的問題在於它使得語言太「神奇」,使得鍵入更容易,但更難以學習和掌握。 – abarnert

0

__iter__()旨在通過對象返回一個迭代。對於已經是迭代器的對象,什麼是迭代器?當然是self

+1

迭代器是一個遍歷迭代器的迭代器,不管它是一個迭代器,而不是它本身,就像列表包含其他值一樣,而不是(必然)它本身。無論如何,爲什麼「iter(an_iterator)」甚至被定義?爲什麼它*有*被定義? (有很好的理由,但你沒有任何名稱)。 – delnan

相關問題