[英]python: iterator from a function
What is an idiomatic way to create an infinite iterator from a function? 从函数创建无限迭代器的惯用方法是什么? For example 例如
from itertools import islice
import random
rand_characters = to_iterator( random.randint(0,256) )
print ' '.join( islice( rand_characters, 100))
would produce 100 random numbers 会产生100个随机数
You want an iterator which continuously yields values until you stop asking it for new ones? 你想要一个迭代器,它不断产生值,直到你不再要求新的值? Simply use 简单地使用
it = iter(function, sentinel)
which calls function()
for each iteration step until the result == sentinel
. 它为每个迭代步骤调用function()
,直到result == sentinel
。
So choose a sentinel which can never be returned by your wanted function, such as None
, in your case. 因此,在您的情况下,选择一个永远不会被您想要的函数返回的标记,例如None
。
rand_iter = lambda start, end: iter(random.randint(start, end), None)
rand_bytes = rand_iter(0, 256)
If you want to monitor some state on your machine, you could do 如果要监视计算机上的某些状态,可以这样做
iter_mystate = iter(getstate, None)
which, in turn, infinitely calls getstate()
for each iteration step. 反过来,它为每个迭代步骤无限调用getstate()
。
But beware of functions returning None
as a valid value! 但要注意将None
作为有效值返回的函数! In this case, you should choose a sentinel which is guaranteed to be unique, maybe an object created for exactly this job: 在这种情况下,您应该选择一个保证唯一的标记,也许是为这个作业创建的对象:
iter_mystate = iter(getstate, object())
Every time I see iter
with 2 arguments, I need to scratch my head an look up the documentation to figure out exactly what is going on. 每次看到iter
以2个参数,我需要帮我头上的查找的文档,弄清楚到底是怎么回事。 Simply because of that, I would probably roll my own: 正因为如此,我可能会自己动手:
def call_forever(callback):
while True:
yield callback()
Or, as stated in the comments by Jon Clements, you could use the itertools.repeatfunc
recipe which allows you to pass arguments to the function as well: 或者,正如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))
Although I think that the function signature def repeatfunc(func,times=None,*args)
is a little awkward. 虽然我认为函数签名def repeatfunc(func,times=None,*args)
有点尴尬。 I'd prefer to pass a tuple as args (it seems more explicit to me, and "explicit is better than implicit"): 我更喜欢将一个元组作为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))
which allows it to be called like: 允许它被称为:
repeatfunc(func,(arg1,arg2,...,argN),times=4) #repeat 4 times
repeatfunc(func,(arg1,arg2,...)) #repeat infinitely
instead of the vanilla version from itertools
: 而不是来自itertools
的vanilla版本:
repeatfunc(func,4,arg1,arg2,...) #repeat 4 times
repeatfunc(func,None,arg1,arg2,...) #repeat infinitely
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.