我正在通过 python 文档学习 itertools:
https://docs.python.org/3/library/itertools.html
最后有一些使用 itertools 命令来做简单事情的食谱,其中之一是 Consumer(),我根本不明白它:
from itertools import *
def consume(iterator, n):
""""Advance the iterator n-steps ahead. If n is none, consume
entirely."""
if n is None:
# feed the entire iterator into a zero-length deque
collections.deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
Run Code Online (Sandbox Code Playgroud)
首先,这个函数声称参数是一个迭代器,但我发现可迭代也可以。我认为可迭代和迭代器之间有区别,对吗?因为islice()不需要迭代器,所以可以使用迭代器
其次,当我尝试时:
aa = iter([1,2,3,4,5])
print(consume(aa, 2))
Run Code Online (Sandbox Code Playgroud)
它给了我None,因为islice(iterator, n, n)无论如何都会如此None,因为 (n, n) 没有要切片的范围。
当然,如果n是None,那么我肯定会得到None
所以看起来无论我在这里做什么,我都会得到None输出,这个函数的目的到底是什么?
consume不应该返回任何有用的东西。正如文档所说,它的目的是推进现有的迭代器。如果您查看aa示例,您会发现它已被高级:
>>> aa = iter([1,2,3,4,5])
... print(consume(aa, 2))
None
>>> next(aa)
3
Run Code Online (Sandbox Code Playgroud)
因为使用它consume是有副作用的,所以你可以在一个“可重迭代”的对象上使用它,但这样做是没有用的。发生的情况是,islice将在该对象上创建一个迭代器,并推进该迭代器,但这不会影响该可迭代对象的后续迭代,因为将创建一个新的迭代器:
# consuming an iterator
aa = iter([1,2,3,4,5])
consume(aa, 2)
print(list(aa))
# [3, 4, 5]
# "consuming" an iterable
aa = [1,2,3,4,5]
consume(aa, 2)
print(list(aa))
# [1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
在后一种情况下,您消耗的只是一个在自身内部创建consume但未返回的临时迭代器,因此它没有可观察到的效果。
(我使用术语“可重迭代”来指代可迭代对象,这些对象每次iter调用时都会在一些稳定的基础数据上生成“新鲜”迭代器。例如,列表是可重迭代的。每个可重迭代对象都是可迭代的,但你可以编写一个不可重复迭代的可迭代对象。)
| 归档时间: |
|
| 查看次数: |
1354 次 |
| 最近记录: |