在 itertools 的 python 文档中,它提供了以下用于推进迭代器 n 步骤的“配方”:
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
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)
我想知道为什么这个配方与这样的东西根本不同(除了消耗整个迭代器的处理):
def other_consume(iterable, n):
for i in xrange(n):
next(iterable, None)
我曾经timeit
确认,正如预期的那样,上述方法要慢得多。允许这种卓越性能的配方中发生了什么?我知道它使用了islice
,但是看着islice
,它似乎在做与上面的代码基本相同的事情:
def islice(iterable, *args):
s = slice(*args)
it = iter(xrange(s.start or 0, s.stop or sys.maxint, s.step or 1))
nexti = next(it)
### it seems as if this loop yields from the iterable n times via enumerate
### how is this different from calling next n times?
for i, element in enumerate(iterable):
if i == nexti:
yield element
nexti = next(it)
注意:即使不是islice
从itertools
我使用上面显示的文档中的 python 等效项来定义它,配方仍然更快..
编辑:timeit
这里的代码:
timeit.timeit('a = iter([random() for i in xrange(1000000)]); consume(a, 1000000)', setup="from __main__ import consume,random", number=10)
timeit.timeit('a = iter([random() for i in xrange(1000000)]); other_consume(a, 1000000)', setup="from __main__ import other_consume,random", number=10)
other_consume
每次我运行它时慢 2.5 倍