12

関数から無限反復子を作成する慣用的な方法は何ですか? 例えば

from itertools import islice
import random
rand_characters = to_iterator( random.randint(0,256) )
print ' '.join( islice( rand_characters, 100))

100個の乱数を生成します

4

2 に答える 2

17

新しい値を求めるのをやめるまで継続的に値を生成するイテレータが必要ですか? 単に使用する

it = iter(function, sentinel)

function()result まで各反復ステップを呼び出します== 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())
于 2012-11-30T14:19:27.960 に答える
8

2 つの引数が表示されるたびにiter、何が起こっているのかを正確に把握するために、頭をかきむしってドキュメントを調べる必要があります。単にその理由で、私はおそらく自分自身を転がすでしょう:

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)関数の署名が少しぎこちないと思いますが。タプルを引数として渡すことをお勧めします (私にはより明示的であり、「明示的は暗黙的よりも優れています」):

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
于 2012-11-30T14:34:38.890 に答える