考虑代码:
def test(data):
for row in data:
print("first loop")
for row in data:
print("second loop")
When data
is an iterator https://docs.python.org/3/glossary.html#term-iterator, for example a list iterator or a generator expression*, this does not work:
>>> test(iter([1, 2]))
first loop
first loop
>>> test((_ for _ in [1, 2]))
first loop
first loop
这打印first loop
有几次,自从data
是非空的。然而,它确实not print second loop
. 为什么会迭代data
第一次工作,但第二次就不行了?我怎样才能让它第二次工作?
除了for
循环,任何类型的迭代都会出现同样的问题:列表/集合/字典理解,将迭代器传递给list()
, sum()
or reduce()
, etc.
另一方面,如果data
是另一种iterable https://docs.python.org/3/glossary.html#term-iterable, 比如一个list
or a range
(两者都是序列 https://docs.python.org/3/glossary.html#term-sequence),两个循环都按预期运行:
>>> test([1, 2])
first loop
first loop
second loop
second loop
>>> test(range(2))
first loop
first loop
second loop
second loop
* 更多示例:
- 文件对象 https://stackoverflow.com/questions/3906137
- 从显式生成器函数创建的生成器 https://stackoverflow.com/questions/1271320
-
filter https://stackoverflow.com/questions/44420135, map https://stackoverflow.com/questions/36486950, and zip https://stackoverflow.com/questions/31683959对象(3.x 中)
- enumerate objects https://stackoverflow.com/questions/23663231
- csv.readers https://stackoverflow.com/questions/6755460
- 中定义的各种迭代器itertools https://docs.python.org/3/library/itertools.html标准库
For general theory and terminology explanation, see What are iterator, iterable, and iteration? https://stackoverflow.com/questions/9884132.
To detect whether the input is an iterator or a "reusable" iterable, see Ensure that an argument can be iterated twice https://stackoverflow.com/questions/70381559.