2014-02-23 26 views
2

隨着iter(),我可以這樣做:iter()內置什麼?

>>> listWalker = iter ([23, 47, 'hike']) 
>>> for x in listWalker: print x, 

但我能做到這一點呢:

>>> listWalker = [23, 47, 'hike'] 
>>> for x in listWalker: print x, 

它增加什麼價值?

+0

有一個很好的例子,使用'iter' [這裏](http://stackoverflow.com/questions/2233204/how-does-zipitersn-work-in-python)。 – GWW

+0

相關:[爲什麼一個Python Iterator需要一個簡單地返回自我的iter方法?](http://stackoverflow.com/questions/21343327/why-does-a-python-iterator-need-an-iter-method- that-simply-returns-self) –

+0

事實上,這個「相關」的問題有一個頂部答案的答案。我傾向於同意投票結束。 –

回答

0

當你在一個變量上做一個for循環時,它隱式地調用你實際通過的iterable的__iter__方法。
你總是使用iter()是當你循環列表,元組......和每一個迭代時的某種方式。

我覺得這種提取物的字節碼可以說服你:

>>> def a(): 
...  for x in [1,2,3]: 
...   print x 
... 
>>> import dis 
>>> dis.dis(a) 
    2   0 SETUP_LOOP    28 (to 31) 
       3 LOAD_CONST    1 (1) 
       6 LOAD_CONST    2 (2) 
       9 LOAD_CONST    3 (3) 
      12 BUILD_LIST    3 
      15 GET_ITER         # <--- get iter is important here 
     >> 16 FOR_ITER    11 (to 30) 
      19 STORE_FAST    0 (x) 

    3   22 LOAD_FAST    0 (x) 
      25 PRINT_ITEM 
      26 PRINT_NEWLINE 
      27 JUMP_ABSOLUTE   16 
     >> 30 POP_BLOCK 
     >> 31 LOAD_CONST    0 (None) 
      34 RETURN_VALUE 


但是,iterables還允許你在Python一些其他的東西,如使用的 next()走進一個迭代,或提高 StopIteration exception。如果您正在處理不同的對象類型並且您想要應用通用算法,那將會非常有用。

+0

Downvoter,請解釋一下? –

4

iter的要點是,它允許您從一個可迭代對象中獲取迭代器並自行使用它,以實現自己的for循環的變體,或者維護跨多個循環的迭代狀態。一個小示例:

it = iter(['HEADER', 0, 1, 2, 3]) # coming from CSV or such 
title = it.next() 
for item in it: 
    # process item 
    ... 

iter更高級的使用流量是由這個分組成語提供:

def in_groups(iterable, n): 
    """Yield element from iterables grouped in tuples of size n.""" 
    it = iter(iterable) 
    iters = [it] * n 
    return zip(*iters) 
+0

+1非常好,*實用*創建同一個迭代器的多個迭代器的例子。 – chepner

5

除了使用iter明確地獲得一個迭代器實現該__iter__方法的對象,有一個鮮爲人知的雙參數形式iter,它使迭代器重複調用一個函數,直到它返回給定的sentinel值。

for line in iter(f.readline, 'EOF'): 
    print line 

前面的代碼將調用f.read(,比如說,一個打開的文件處理f),直到它讀出由該字符串EOF的一條線。這與寫作大致相同

for line in f: 
    if line == "EOF": 
     break 
    print line 

此外,迭代器可能是與它迭代的對象不同的對象。對於list類型,這是正確的。這意味着您可以創建兩個迭代器,這兩個迭代器在同一對象上獨立重複

itr1 = iter(mylist) 
itr2 = iter(mylist) 

x = next(itr1) # First item of mylist 
y = next(itr1) # Second item of my list 
z = next(itr2) # First item of mylist, not the third 

文件句柄,但是,作爲他們自己的迭代:

>>> f = open('.bashrc') 
>>> id(f) 
4454569712 
>>> id(iter(f)) 
4454569712 

一般來說,iter返回的對象取決於該對象的類型實現的__iter__方法。

+1

+1優秀的答案,涵蓋了「iter」的「正常」使用和雙參數形式。您可能希望更精確地指出迭代器**可以是它所迭代的對象的不同對象。許多對象,特別是文件對象,還有迭代器本身,都是它們自己的迭代器。 – user4815162342

0

the docs

ITER(O [,定點])

[...]如果沒有第二個參數,鄰必須是支持 迭代協議(該__iter__()一個集合對象方法),或者它必須支持 序列協議(__getitem__()方法,整數參數 從0開始)。如果它不支持這兩種協議,則會引發 TypeError。 [...]

所以它從一個對象構造一個迭代器。正如你所說,這是在循環和理解中自動完成的,但有些時候你想獲得一個迭代器並直接處理它。只要把它放在你腦海的後面,直到你需要它爲止。

當使用第二個參數:

如果第二個參數,前哨,給定,然後按o必須是一個可調用對象。 在這種情況下創建的迭代器將爲每個調用 的next()方法調用o而不帶參數;如果返回的值等於哨兵,則 將會提高StopIteration,否則將返回該值。

這是傳統風格的功能,如file.read(bufsize)具有反覆調用,直到它返回""許多有用的東西,但尤其如此。可以將其轉換爲iter(lambda : file.read(bufsize), "")的迭代器。乾淨又幹淨!

相關問題