繁体   English   中英

在 python 中使用生成器制作惰性流

[英]Using generators to make lazy streams in python

我一直在搞乱 python 中的流,并一直在尝试生成汉明数(所有素数仅为 2、3 或 5 的数字)。 Dijkstra 描述的这样做的标准方法是观察:

  1. 汉明数列从 1 开始。
  2. 序列中的其余值的形式为 2h、3h 和 5h,其中 h 是任何汉明数。
  3. h是通过输出值1生成的,然后合并2h、3h、5h

我的实现是这样的:

def hamming():
    yield 1
    yield from merge(scale_stream(hamming(), 2), scale_stream(hamming(), 3))

def merge(s1, s2):
  x1, x2 = next(s1), next(s2)
  while True:
    if x1 < x2:
        yield x1
        x1 = next(s1)
    elif x1 > x2:
        yield x2
        x2 = next(s2)
    else:
        yield x1
        x1, x2 = next(s1), next(s2)

def scale_stream(stream, scalar):
    for e in stream:
        yield e * scalar

def stream_index(stream, n):
    for i, e in enumerate(stream):
        if i+1 == n:
            return e

print(stream_index(hamming(), 300))

这确实正确地产生了 stream 的汉明数,但是无论出于何种原因,它产生的时间越长,花费的时间就越长,即使理论上时间复杂度应该是 O(N)。

我以前玩过其他流,但我对它们的直觉很弱,所以我不知道这里发生了什么。 我认为问题在于我定义的递归方式 hamming(); 我不知道每次调用 hamming 都可能产生必须并行运行的新版本进程从而减慢速度是否是一个问题。

老实说,尽管就像我说的那样,我对运行它时实际发生的情况知之甚少,调试也无济于事,因此,如果有更多经验的人可以启发我,我将不胜感激。

您进入 stream 的距离越远,您需要合并的重复项就越多。 数字 2**4 * 3 **4 = 1296 将在您的倍数 stream 中出现 70 次(8 选 4),并且您的程序将花费更多时间合并重复项而不是输出新项。

你 go 越远,你要处理的重复越多。 没有理由期望您的程序是线性的。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM