Function to call function again?

Consider the hypothetical function repeatcall , which takes no-args as the called func and a positive integer n and returns a list whose members are obtained by executing func() n times. It supports an endless stream of silly khinks, such as:

 >>> 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 can swear I saw a function like repeatcall somewhere in the standard Python 2.x libraries, but I can't find it. If I hadn’t dreamed about it, where can I find it in the standard library ?

PS: I know that it is trivial to roll one, but I do not like to reinvent the wheels, especially those that are already in the standard library. I do not ask how to collapse.

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

+6
source share
4 answers

You saw this in standard library documents, not in the standard library itself.

He repeatfunc from 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 accepts arguments and should (theoretically) work better than list comprehension, because func needs to be searched only once. repeat also faster than range if you are not actually using a counter.

+13
source

Do you mean something like this?

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

Seems succinct enough?

+3
source

There is a reason why this does not exist: an idiomatic way of encoding a function that takes no arguments for each call, and returns something new to encode it as a generator.

Then you must use an expression to compile a list or a generator to call it as many times as you want: [next(gen) for i in xrange(5)] . Even better, gen can be the result of a generator expression like (id(dict()) for i in (itertools.repeat(None))) .

Thus, python does not support the library because it supports it syntactically.

+3
source

You can use the apply built-in function for this purpose.

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

Note ** From the manual Using apply () is equivalent to the function (* args, ** keywords).

So repeatcall can also be written as

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

Source: https://habr.com/ru/post/912635/


All Articles