7

repeatcall引数として呼び出し可能な引数なしfuncと正の整数を取りn、実行時間によってメンバーが取得されるリストを返す架空の関数について考えてみますfunc() n。それは次のような愚かなhijinksの無限の流れをサポートします:

>>> repeatcall(lambda: id(dict()), 5)
[45789920, 45788064, 45807216, 45634816, 45798640]

>>> urandom = lambda: struct.unpack('Q', open('/dev/urandom').read(8))[0]
>>> repeatcall(urandom, 3)
[3199039843823449742, 14990726001693341311L, 11583468019313082272L]

>>> class Counter(itertools.count): __call__ = itertools.count.next
>>> repeatcall(Counter(100, -2), 4)
[100, 98, 96, 94]

Python 2.x標準ライブラリのどこかにあるような関数を見たことがあると断言できますがrepeatcall、見つかりません。これを夢見ていなかった場合、標準ライブラリのどこで見つけることができますか?

PS:自分で転がすのは簡単なことですが、車輪の再発明は嫌いです。特に、すでに標準ライブラリにあるものはそうです。私は自分自身を転がす方法を尋ねていません。

編集:コーディング方法を尋ねていないことをさらに明確にrepeatcallしました。

4

5 に答える 5

14

これは、標準ライブラリ自体ではなく、標準ライブラリのドキュメントで見たことがあります。

それrepeatfuncitertoolsレシピからです:

def repeatfunc(func, times=None, *args):
    """Repeat calls to func with specified arguments.

    Example:  repeatfunc(random.random)
    """
    if times is None:
        return starmap(func, repeat(args))
    return starmap(func, repeat(args, times))

これは引数を許可し、(理論的には) リスト内包表記よりも優れたパフォーマンスを発揮するはずfuncです。実際にカウンターを使用していない場合repeatよりも高速です。range

于 2012-04-06T20:42:49.597 に答える
4

これが存在しないのには理由があります。呼び出しごとに引数を取らず、何か新しいものを返す関数をコーディングする慣用的な方法は、ジェネレーターとしてコーディングすることです。

次に、リスト内包表記またはジェネレーター式を使用して、何度でも呼び出すことができます: [next(gen) for i in xrange(5)]. さらに良いgenことに、それ自体が のようなジェネレータ式の結果になることもあります(id(dict()) for i in (itertools.repeat(None)))

したがって、Python は構文的にサポートしているため、これに対するライブラリ サポートはありません。

于 2012-04-07T07:38:33.803 に答える
3

次のような意味ですか?:

>> from random import random
>> print [random() for x in range(5)]
[0.015015074309405185,
 0.7877023608913573,
 0.2940706206824023,
 0.7140457069245207,
 0.07868376815555878]

十分に簡潔に見えますよね?

于 2012-04-06T20:39:37.810 に答える
2

この目的のために、 apply組み込み関数を使用できます。

>>> def repeatcall(func,n):
    [apply(func) for i in range(0,n)]

>>> repeatcall(lambda: id(dict()), 5)
[56422096, 56422240, 56447024, 56447168, 56447312]

>>> import itertools
>>> class Counter(itertools.count): __call__ = itertools.count.next

>>> repeatcall(Counter(100, -2), 4)
[100, 98, 96, 94]
>>> 

注意** マニュアルより apply() の使用は function(*args, **keywords) と同等です。

したがって、repeatcall は次のようにも記述できます。

>>> def repeatcall(func,n):
    [func() for i in range(0,n)]
于 2012-04-06T20:39:56.643 に答える