【问题标题】:Can iterators be iterated only once? [duplicate]迭代器只能迭代一次吗? [复制]
【发布时间】:2017-07-05 17:51:12
【问题描述】:

考虑以下示例:

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

重复使用同一个迭代器两次是否安全?

【问题讨论】:

  • 这个简单的问题居然没人回答,真是奇怪。好吧,下次我会尝试更改搜索条件。
  • 你的标题混淆了迭代器和迭代器,有些迭代器可以迭代多次(如lists)
  • 嗯,我明白了。尽管问题被标记为重复,我是否应该编辑标题?
  • @Chris_Rands 你的评论混淆了“你的”和“你是”。

标签: python python-3.x iterator


【解决方案1】:

不,这不安全。迭代器不是序列。下面是使用生成器的 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 中的项目保存到临时tuple 或list 中:

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

【讨论】:

  • 或使用itertools.tee 或将其转换为列表以重复使用。
猜你喜欢
  • 1970-01-01
  • 2015-03-29
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
相关资源
最近更新 更多