【问题标题】:Pythonic way to re-apply a function to its own output n times?将函数重新应用到自己的输出 n 次的 Pythonic 方式?
【发布时间】:2017-08-26 23:46:21
【问题描述】:

假设有一些有用的转换函数,例如random_spelling_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!")

有没有内置的或其他更好的方法来做到这一点?

它不需要处理可变长度的 args 或关键字 args,但它可以。该函数将被大规模调用,但 n 的值会很小,并且参数和返回值的大小会很小。

我们可以称它为reduce,但这个名称当然是用于可以执行此操作的函数以及更多功能,并在 Python 3 中被删除。这里是 Guido's argument

所以在我看来,reduce() 的适用性非常有限 关联运算符,在所有其他情况下最好写出 明确的累积循环。

【问题讨论】:

  • 查看 R 的解决方案:stackoverflow.com/questions/29237136/…
  • 我认为您的循环没有任何问题或“un-pythonic”。是的,也许你可以用一行而不是三行来做,但有什么用呢?立即清楚它应该做什么,使其 very pythonic 恕我直言。
  • @tobias_k 我同意它按原样可读(且高效),我只是想知道是否有约定或者我是否复制了某些内容,因为这项任务看起来很普通。

标签: python python-3.x tail-recursion built-in


【解决方案1】:

reduce 仍然可以在 python 3 中使用 functools 模块。我真的不知道它是否更 Pythonic,但您可以通过以下方式在一行中实现它:

from functools import reduce

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

【讨论】:

  • 谢谢,循环更具可读性并保存导入,所以在实践中我会选择它而不是它,但对于那些好奇如何使用reduce 完成它的人来说,这是一个很好的答案.
【解决方案2】:

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

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

【讨论】:

  • 可以缩短为return reapply(...) if n else arg,但恕我直言,既不清晰也不更好(递归限制?)。
【解决方案3】:

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

foo = reapply(3, random_spelling_error, foo)

或者是一个简单的for 循环,即多行:

for _ in range(3):
    foo = random_spelling_error(foo)

更新:根据你的评论

假设有许多我可能想要应用的转换函数。

为什么不试试这样的:

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)

【讨论】:

  • 假设有许多我可能想要应用的转换函数。 (有。)函数必须是变量也可能有其他原因。
  • @A.M.Bittlingmayer 查看更新。我只是不认为你应该强迫未来的开发者(甚至未来你自己)去阅读 reapply 所做的事情,因为它可以在几行 Python 中完成。
  • 如果你真的确实需要一个函数,那么你的方法是最好的方法,保持简单。但我认为你不应该在这里使用函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 2017-09-15
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2020-03-25
相关资源
最近更新 更多