简体   繁体   English

Function 反复拨打 function?

[英]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.考虑假设的 function repeatcall ,它采用 arguments 一个无参数可调用func和一个正数 integer n ,并返回一个列表,其成员是通过执行func() n次获得的。 It supports an infinite stream of silly hijinks like:它支持无限的 stream 傻笑,例如:

>>> 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.我可以发誓,我在 Python 2.x 标准库的某处看到过类似repeatcall的 repeatcall,但我找不到它。 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. PS:我知道自己动手是微不足道的,但我讨厌重新发明轮子,尤其是那些已经在标准库中的轮子。 I am not asking how to roll my own.不是在问如何推出自己的。

Edit: made it even more explicit that I am not asking how to code repeatcall .编辑:更明确地说我不是在问如何编写repeatcall代码。

You've seen this in the standard library docs, not the standard library itself.您已经在标准库文档中看到了这一点,而不是标准库本身。

It's repeatfunc from the itertools recipes :它是itertools食谱中的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))

It allows arguments and should (theoretically) perform better than a list comprehension because func only has to be looked up once.它允许 arguments 并且(理论上)应该比列表理解表现得更好,因为func只需要查找一次。 repeat is also faster than range for when you're not actually using the counter.当您实际上不使用计数器时, repeat也比range快。

There's a reason this doesn't exist: the idiomatic way to code a function that doesn't take arguments on each invocation, and returns something new is to code it as a generator.这不存在是有原因的:编写 function 的惯用方法不会在每次调用时使用 arguments,并返回一些新的东西是将其编码为生成器。

You would then use a list comprehension or generator expression to call it as many times as you like: [next(gen) for i in xrange(5)] .然后,您可以使用列表推导式或生成器表达式来多次调用它: [next(gen) for i in xrange(5)] Better yet, gen can itself be the result of a generator expression like (id(dict()) for i in (itertools.repeat(None))) .更好的是, gen本身可以是生成器表达式的结果,例如(id(dict()) for i in (itertools.repeat(None)))

Thus, python has no library support for this because it supports it syntactically.因此, python 没有库支持它,因为它在语法上支持它。

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 no?似乎足够简洁不是吗?

You can use the apply built-in function for this purpose为此,您可以使用内置的应用程序 function

>>> 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 The use of apply() is equivalent to function(*args, **keywords).注意** 从手册中 apply() 的使用等同于 function(*args, **keywords)。

So repeatcall can also be written as所以repeatcall也可以写成

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

While reading comments here I realized that iter(foo, expr) will create an infinite iterator of the result of foo as long as it never equals expr .在这里阅读评论时,我意识到iter(foo, expr)将创建foo结果的无限迭代器,只要它永远不等于expr

for the example in the question, iter(lambda: id(dict()), None) will create an infinite iterator of ids of dicts.对于问题中的示例, iter(lambda: id(dict()), None)将创建一个无限迭代器的 id 的字典。

While not a direct answer to this question, I found it useful since in my usecase I wanted it to be part of a finite zip expression anyways and just needed the iterator to keep producing elements.虽然不是这个问题的直接答案,但我发现它很有用,因为在我的用例中我希望它无论如何都是有限zip表达式的一部分并且只需要迭代器来继续生成元素。

hopefully this might help others that stumble upon this question希望这可以帮助其他偶然发现这个问题的人

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Python中重复调用同一函数 - Calling The Same Function Repeatedly In Python 使用全局变量而不是调用重复返回所述变量的函数 - Using a global variable versus calling the function that returns said variable repeatedly 如何编写函数,并在反复调用它的同时保持返回最大值 - How to write a function keeping return the maximum value while calling it repeatedly 是否有 Python 标准库函数可以通过重复调用函数来创建生成器? - Is there a Python standard library function to create a generator from repeatedly calling a functional? 重复并行运行一个函数 - Repeatedly run a function in parallel 定义的函数反复循环 - defined function repeatedly looping Python列表理解。 通过重复调用函数直到返回预定义值来生成列表 - Python List Comprehension. Generating a List by repeatedly calling a function till it returns a predefined value 直接调用函数来更新 matplotlib 图形有效,从循环中重复调用它只显示最终结果 - Direct calls to function to update matplotlib figure works, calling it repeatedly from a loop only shows final result 如何使用函数运行脚本? (反复) - How to run script with a function? (repeatedly) 在函数中返回值以在同一函数中重复使用? - Returning value in a function to use in the same function repeatedly?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM