sta*_*onk 9 python iterator cycle python-itertools
Python的itertools.cycle()文档给出了伪代码实现:
def cycle(iterable):
# cycle('ABCD') --> A B C D A B C D A B C D ...
saved = []
for element in iterable:
yield element
saved.append(element)
while saved:
for element in saved:
yield element
Run Code Online (Sandbox Code Playgroud)
下面,它指出:"注意,该工具包的这个成员可能需要大量的辅助存储(取决于可迭代的长度)."
我基本上是沿着这条路走,除了我这样做,这不需要创建iterable的副本:
def loop(iterable):
it = iterable.__iter__()
while True:
try:
yield it.next()
except StopIteration:
it = iterable.__iter__()
yield it.next()
x = {1, 2, 3}
hard_limit = 6
for i in loop(x):
if hard_limit <= 0:
break
print i
hard_limit -= 1
Run Code Online (Sandbox Code Playgroud)
打印:
1
2
3
1
2
3
Run Code Online (Sandbox Code Playgroud)
是的,我意识到我的实现不适用于str,但可以实现.我更好奇为什么它会创建另一个副本.我有一种感觉它与垃圾收集有关,但我在Python的这个领域没有很好的研究.
谢谢!
Mar*_*ers 14
Iterables只能迭代一次.
您可以在循环中创建一个新的 iterable.循环不能这样做,它必须与你传入的任何东西一起工作.cycle不能简单地重新创建迭代.因此,它被迫存储原始迭代器产生的所有元素.
如果您要传入以下生成器,则loop()失败:
def finite_generator(source=[3, 2, 1]):
while source:
yield source.pop()
Run Code Online (Sandbox Code Playgroud)
现在你的loop()产品:
>>> hard_limit = 6
>>> for i in loop(finite_generator()):
... if hard_limit <= 0:
... break
... print i
... hard_limit -= 1
...
1
2
3
Run Code Online (Sandbox Code Playgroud)
你的代码只适用于序列,对于这些序列,使用cycle()会过度; cycle()在这种情况下你不需要存储负担.简化为:
def loop_sequence(seq):
while True:
for elem in seq:
yield elem
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1471 次 |
| 最近记录: |