Search code examples
pythoniteratoriteration

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.


Solution

  • 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.