从自己的输出中累积函数

vaj7vani  于 2021-09-08  发布在  Java
关注(0)|答案(2)|浏览(432)

我有下面的发电机,它有点像 itertools.accumulate ,但它从函数自身的输出而不是iterable获取下一个输入:

  1. def turboaccumulate(f, initial):
  2. x = initial
  3. while True:
  4. x = f(x)
  5. yield x

标准库中是否包含类似的内容,或者python文档中是否包含推荐的方法?我在大约20分钟的搜索中找不到一个。
或者,至少:这个操作叫什么(我非常怀疑“turbo accumulate”是公认的名称。)
这篇文章的背景是试图将难以理解的lisp庞然大物解析成凡人都能理解的东西,我想说的是:

  1. def blum_blum_shub(p, q, s):
  2. #assert coprime(p, q)
  3. M = p * q
  4. return turboaccumulate(lambda x: pow(x, 2, M), s)

然而,最后的函数调用看起来非常愚蠢,所以我想知道它是否存在于标准库中,或者至少有一个更容易识别的名称。

lf5gs5x2

lf5gs5x21#

不幸的是,据我所知,python并没有这样的内置功能。如果您需要此功能,您的生成器功能可能会尽可能干净。 iter 不太为人所知的第二种形式几乎能满足你的需求,但不幸的是,他们使它完全起到了副作用,这打破了这种模式。要使用它,您需要类似于以下内容的 Package :

  1. def fp_iter(f, initial):
  2. acc = initial
  3. def wrapper():
  4. nonlocal acc
  5. return (acc := f(acc))
  6. return iter(wrapper, object())
  7. >>> i = fp_iter(lambda n: n + 1, 0)
  8. >>> next(i)
  9. 1
  10. >>> next(i)
  11. 2
  12. >>> next(i)
  13. 3

在这一点上,我会用你的发电机。
它的名字,我知道这是 iterate 由于我使用clojure的时间而导致的函数。这类似于数学中的迭代,所以我认为这是一个合适的名称:
在数学中,迭代可以指迭代函数的过程,即重复应用函数,使用一次迭代的输出作为下一次迭代的输入。

展开查看全部
nszi6y05

nszi6y052#

你可以用 accumulate 要以某种非标准方式实现这一点:

  1. from itertools import accumulate, count
  2. def turboaccumulate(f, initial):
  3. return accumulate(count(), lambda x, y: f(x), initial=initial)

您可以使用任何无限迭代器而不是 count 因为它的值被忽略( y 从不使用)。

相关问题