重复调用函数的功能?

时间:2012-04-06 20:32:06

标签: python iterator iteration

考虑假设函数repeatcall,它将no-args可调用func和正整数n作为参数,并返回一个列表,其成员是通过执行{{1}获得的} func()次。它支持无限的愚蠢的hijinks流,如:

n

我可以发誓我在Python 2.x标准库中看到了>>> 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] 之类的函数,但我找不到它。如果我没有想到这一点,我可以找到标准库中的 吗?

PS:我知道推出自己的产品是微不足道的,但我讨厌重新发明轮子,尤其是那些已经在标准库中的轮子。我询问如何自己动手。

编辑:让更明确,我不会问如何编码repeatcall

4 个答案:

答案 0 :(得分:13)

您已在标准库文档中看到过这种情况,而不是标准库本身。

来自itertools recipes

repeatfunc
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快。

答案 1 :(得分:3)

你的意思是这样的吗?:

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

似乎足够简洁吗?

答案 2 :(得分:3)

这是不存在的原因:对每个调用不带参数的函数进行编码的惯用方法,以及返回新内容的方法是将其编码为生成器。

然后,您可以使用列表推导或生成器表达式多次调用它:[next(gen) for i in xrange(5)]。更好的是,gen本身可以是(id(dict()) for i in (itertools.repeat(None)))等生成器表达式的结果。

因此, python没有库支持,因为它在语法上支持它。

答案 3 :(得分: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()的使用等同于函数(* args,** keywords)。

所以repeatcall也可以写成

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