2017-02-16 140 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'或将其转换为一个列表重用。 –