2017-08-02 50 views
4

我已經閱讀了我的資料,它告訴python迭代器必須同時有__iter____next__方法,但是迭代只需要__iter__。我檢查一個清單,發現它沒有__next__方法。當使用iter()時,它將成爲迭代器。這意味着iter()會將__next__方法添加到列表中以將其轉換爲迭代器?如果是的話,這是怎麼發生的?內置函數iter()如何將python列表轉換爲迭代器?

+1

尼斯摘要:http://nvie.com/posts/iterators-vs-generators/ – mkrieger1

回答

4

iter返回迭代器,它不會將列表轉換爲迭代器。它根本不修改列表,當然,該列表沒有得到__next__方法。

>>> x = [1,2] 
>>> it = iter(x) 
>>> it 
<list_iterator object at 0x101c021d0> 
>>> x.__next__ 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'list' object has no attribute '__next__' 
>>> 

列表是iterables,不迭代器。他們實現一個__iter__方法,因此它們是可迭代:

>>> x.__iter__ 
<method-wrapper '__iter__' of list object at 0x101bcf248> 

但不是__next__,因此,他們不是迭代器:

>>> next(x) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'list' object is not an iterator 

迭代器本身是可迭代的,顧名思義,因爲他們實施__iter__爲好。試想一下:

>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> it = iter(x) 
>>> it 
<list_iterator object at 0x101c02358> 
>>> it.__iter__ 
<method-wrapper '__iter__' of list_iterator object at 0x101c02358> 

大多數 迭代器,當你對他們使用iter應該簡單地返回自己:

>>> it2 = iter(it) 
>>> it, it2 
(<list_iterator object at 0x101c02358>, <list_iterator object at 0x101c02358>) 
>>> it is it2 
True 
>>> 

事實上,這是一個requirement of the iterator protocol:需要

」迭代器有一個__iter__()方法返回 iter ator對象本身,所以每個迭代器也是可迭代的,並且可能在其他迭代器被接受的大多數地方使用 。

注意,同樣,他們是相同的迭代器

>>> next(it) 
1 
>>> next(it2) 
2 
>>> next(it) 
3 
>>> next(it) 
4 
>>> next(it2) 
5 
>>> list(it) 
[6, 7, 8, 9] 
>>> next(it2) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

因此,一個迭代實現__iter____next__,一個迭代只是意味着它實現__iter__。什麼是返回__iter__是一個迭代器,所以必須執行__next__

+0

關鍵是,'__next__'方法是_on thing_ iter'返回 – Eevee

+0

注意:*所有*迭代器必須有一個' __iter__'實現返回迭代器對象本身,而不僅僅是「最」。這是[迭代器協議的要求](https://docs.python.org/3/glossary.html#term-iterator):「迭代器需要有一個返回迭代器對象的__iter __()方法,因此每個迭代器也是可迭代的,並且可以在其他迭代器被接受的大多數地方使用。「Python的其他部分依賴於此;一種規範而有效的鴨式打印方法來測試某些東西是否爲迭代器就是測試'obj is iter iter(someobj)'。 – ShadowRanger

+0

@ShadowRanger是的,你是絕對正確的。沒有什麼能阻止你打破這個,但我當然不會建議這樣做,我會更新以反映這一點。 –

相關問題