2017-02-16 139 views
1

請看下面的例子:迭代器只能迭代一次嗎?

def foo(iterator): 
    return sum(iterator)/max(iterator) 

是否安全,重複使用相同的迭代器兩次?

+0

真的很奇怪,沒有人回答過這個簡單的問題。那麼,下次我會嘗試更改我的搜索字詞。 – farsil

+1

你的標題混淆了迭代器和迭代器,有些迭代器可以迭代多次(比如'lists') –

+0

嗯,我明白了。我應該編輯標題,儘管問題被標記爲重複? – farsil

回答

2

不,它不安全。迭代器不是序列。下面是使用一臺發電機與foo()功能的情況發生,這本身就是一個迭代器:

>>> foo(x for x in range(10)) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in foo 
ValueError: max() arg is an empty sequence 

這是因爲迭代器已經在其結束時後sum()完成自己的工作,所以max()正從它沒有其他項目。通常,重置迭代器是不可能的,以便它可以再次循環。爲了使foo()功能很好地支持迭代器,它必須通過保存的物品從iterator重寫,這樣迭代通過循環只有一次,例如到一個臨時tuplelist

def foo(iterator): 
    iterable = list(iterator) 
    return sum(iterable)/max(iterable) 

,或者,如果iterator產生了大量的項目,由仔細使用for循環處理它:

def foo(iterator): 
    # allows iterables like lists or tuples to be passed as arguments 
    iterator = iter(iterator) 

    try: 
     max_ = next(iterator) 
     sum_ = max_ 
    except StopIteration: 
     # iterator yields no items, return some default value 
     return 0.0 

    for element in iterator: 
     sum_ += element 
     max_ = max(max_, element) 

    return sum_/max_ 

這將產生正確的結果:

>>> foo(x for x in range(10)) 
5.0 
+2

或者使用'itertools.tee'或將其轉換爲一個列表重用。 –