微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从自己的输出累加函数

如何解决从自己的输出累加函数

我有以下生成器,它有点像 itertools.accumulate,除了它从函数自己的输出获取一个输入,而不是从可迭代对象中获取

def turboaccumulate(f,initial):
    x = initial
    while True:
        x = f(x)
        yield x

标准库中是否包含类似的内容,或者 Python 文档中是否包含推荐的配方?我在大约 20 分钟的搜索中找不到一个

或者,至少:这个操作叫什么?(我高度怀疑“turbo-accumulate”是公认的名称为它。)


本文的背景是努力将 inscrutable lisp behemoth here 解析为凡人可以理解的东西,我归结为:

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

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

解决方法

不幸的是,据我所知,Python 没有这样的内置功能。如果您需要此功能,那么您的生成器函数可能与您所获得的一样干净。

iter 鲜为人知的第二形式几乎可以满足您的需求,但不幸的是,他们使它成为纯粹的副作用,这打破了模式。要使用它,您需要一个与此类似的包装器:

def fp_iter(f,initial):
    acc = initial
    def wrapper():
        nonlocal acc
        return (acc := f(acc))

    return iter(wrapper,object())

>>> i = fp_iter(lambda n: n + 1,0)
>>> next(i)
1
>>> next(i)
2
>>> next(i)
3

到那时,我只会使用你的发电机。


就其名称而言,由于我使用 Clojure 的时间,我将其称为 iterate function。这类似于 iteration in math,所以我认为这与您会得到的名称一样合适:

在数学中,迭代可以指迭代一个函数的过程,即重复应用一个函数,使用一次迭代的输出作为下一次迭代的输入。

,

您可以使用 accumulate 以某种非标准方式实现此目的:

from itertools import accumulate,count

def turboaccumulate(f,initial):
    return accumulate(count(),lambda x,y: f(x),initial=initial)

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。