Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function for calling a function repeatedly?

Consider the hypothetical function repeatcall, that takes as arguments a no-args callable func and a positive integer n, and returns a list whose members are obtained by executing func() n times. It supports an infinite stream of silly hijinks like:

>>> 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]

I could swear that I've seen a function like repeatcall somewhere in the Python 2.x standard libraries, but I can't find it. If I didn't dream this, where in the standard library can I find it?

PS: I know it's trivial to roll one's own, but I hate to reinvent wheels, especially those are already in the standard library. I am not asking how to roll my own.

Edit: made it even more explicit that I am not asking how to code repeatcall.

like image 646
kjo Avatar asked Apr 06 '12 20:04

kjo


1 Answers

You've seen this in the standard library docs, not the standard library itself.

It's repeatfunc from the itertools recipes:

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))

It allows arguments and should (theoretically) perform better than a list comprehension because func only has to be looked up once. repeat is also faster than range for when you're not actually using the counter.

like image 148
agf Avatar answered Nov 22 '22 13:11

agf