Pythonic将函数重新应用到自己的输出n次的方法?

Pythonic将函数重新应用到自己的输出n次的方法?,python,python-3.x,tail-recursion,built-in,Python,Python 3.x,Tail Recursion,Built In,假设有一些有用的转换函数,例如random\u spelling\u error,我们希望应用n次 我的临时解决方案如下所示: def reapply(n, fn, arg): for i in range(n): arg = fn(arg) return arg reapply(3, random_spelling_error, "This is not a test!") modifiers = (random_spelling_error, anoth

假设有一些有用的转换函数,例如
random\u spelling\u error
,我们希望应用n次

我的临时解决方案如下所示:

def reapply(n, fn, arg):
    for i in range(n):
        arg = fn(arg)
    return arg


reapply(3, random_spelling_error, "This is not a test!")
modifiers = (random_spelling_error, another_function, apply_this_too)
for modifier in modifiers:
    for _ in range(3):
        foo = modifier(foo)
有没有内置的或其他更好的方法来实现这一点

它不需要处理可变长度的参数或关键字参数,但可以。函数将按比例调用,但n的值将很低,参数和返回值的大小将很小

我们可以称之为
reduce
,但是这个名字当然是为了一个可以做这件事的函数而取的,并且在Python3中被删除了。这是:

所以在我看来,reduce()的适用性在很大程度上局限于 关联运算符,在所有其他情况下,最好写出 累加循环是显式的


有些人喜欢递归,但并不总是明显“更好”

def reapply(n, fn, arg):
    if n:
        arg = reapply(n-1, fn, fn(arg))
    return arg


reapply(1, lambda x: x**2, 2)
Out[161]: 4

reapply(2, lambda x: x**2, 2)
Out[162]: 16

使用
functools
模块,Python3中仍然可以使用
reduce
。我真的不知道它是否更像蟒蛇,但以下是您如何在一行中实现它:

from functools import reduce

def reapply(n, fn, arg):
    return reduce(lambda x, _: fn(x), range(n), arg)

完全摆脱自定义函数,您试图将两个可读的行压缩为一个混乱的函数调用。你认为哪一个更容易阅读和理解,你的方式:

foo = reapply(3, random_spelling_error, foo)
或者是一个简单的
for
循环,它是多行:

for _ in range(3):
    foo = random_spelling_error(foo)
更新:根据您的评论


让我们假设我可能想要应用许多转换函数

为什么不试试这样的东西:

def reapply(n, fn, arg):
    for i in range(n):
        arg = fn(arg)
    return arg


reapply(3, random_spelling_error, "This is not a test!")
modifiers = (random_spelling_error, another_function, apply_this_too)
for modifier in modifiers:
    for _ in range(3):
        foo = modifier(foo)
或者,如果不同函数需要不同的重复次数,请尝试创建元组列表:

modifiers = [
    (random_spelling_error, 5),
    (another_function, 3),
    ...
]

for modifier, count in modifiers:
    for _ in range(count):
        foo = modifier(foo)

请参阅R的解决方案:我不认为您的循环有任何错误或“非pythonic”。是的,也许你可以用一行而不是三行来做,但是为什么呢?它应该做什么马上就很清楚了,这使它非常像pythonic IMHO。@tobias_k我同意它是可读的(和有效的),我只是想知道是否有一个约定或者我是否复制了一些东西,因为任务看起来很普通。可以缩短为
返回重新应用(…)如果n其他arg
,但是IMHO既不清楚也不更好(递归限制?)。谢谢你,循环更可读并且保存了导入,所以在实践中我会选择它而不是它,但是对于那些好奇如何使用
reduce
的人来说,这是一个很好的答案。让我们假设有许多转换函数我可能想要应用。(有。)函数必须是变量也可能有其他原因。@a.M.Bittlingmayer请参阅更新。我只是不认为你应该强迫未来的开发人员(甚至未来的你自己)去阅读
重新应用
所做的事情,而这一切都可以在几行Python中完成。如果你真的需要函数,那么你的方法是最好的方法,保持简单。但我认为你不应该在这里使用函数。