从函数创建无限迭代器的惯用方法是什么?例如
from itertools import islice
import random
rand_characters = to_iterator( random.randint(0,256) )
print ' '.join( islice( rand_characters, 100))
会产生 100 个随机数
您想要一个不断产生值的迭代器,直到您停止向它询问新值?只需使用
it = iter(function, sentinel)
它要求function()
每个迭代步骤直到结果== sentinel
。
所以选择一个你想要的函数永远不会返回的哨兵,例如None
,在你的情况下。
rand_iter = lambda start, end: iter(random.randint(start, end), None)
rand_bytes = rand_iter(0, 256)
如果您想监视机器上的某些状态,您可以这样做
iter_mystate = iter(getstate, None)
这反过来又无限地调用getstate()
每个迭代步骤。
但要注意函数None
作为有效值返回!在这种情况下,您应该选择一个保证唯一的哨兵,也许是为这个工作创建的对象:
iter_mystate = iter(getstate, object())
每次我看到iter
2 个参数时,我都需要挠头并查看文档以弄清楚到底发生了什么。正因为如此,我可能会自己动手:
def call_forever(callback):
while True:
yield callback()
或者,正如 Jon Clements 在评论中所述,您可以使用itertools.repeatfunc
允许您将参数传递给函数的配方:
import itertools as it
def repeatfunc(func, times=None, *args):
"""
Repeat calls to func with specified arguments.
Example: repeatfunc(random.random)
"""
if times is None:
return it.starmap(func, it.repeat(args))
return it.starmap(func, it.repeat(args, times))
虽然我觉得函数签名def repeatfunc(func,times=None,*args)
有点别扭。我更喜欢将元组作为 args 传递(对我来说这似乎更明确,并且“显式优于隐式”):
import itertools as it
def repeatfunc(func, args=(),times=None):
"""
Repeat calls to func with specified arguments.
Example: repeatfunc(random.random)
"""
if times is None:
return it.starmap(func, it.repeat(args))
return it.starmap(func, it.repeat(args, times))
这允许它被称为:
repeatfunc(func,(arg1,arg2,...,argN),times=4) #repeat 4 times
repeatfunc(func,(arg1,arg2,...)) #repeat infinitely
而不是来自的香草版本itertools
:
repeatfunc(func,4,arg1,arg2,...) #repeat 4 times
repeatfunc(func,None,arg1,arg2,...) #repeat infinitely