Python如何生成所有对项

标签 python algorithm generator

我想要一个所有“成对术语”的无限生成器。其中 0 是对项,两个对项的元组 (a,b) 是对项。重要的是每个项目至少出现一次(在有限的时间内),但只出现一次会更有效率。

我想到了

def pairTerms():
  yield 0
  generated=[]
  diagonal=-1 #sum indices in generated of the pairs we are generating, could be replaced by len(generated)-1
  for t in pairTerms():
    generated.append(t)
    diagonal+=1
    for i,a in enumerate(generated):
      yield (a,generated[diagonal-i])

但这很快就会填满内存。 编辑:这种方法实际上似乎工作得很好,在填满内存之前生成了超过 1000 万个术语。

或者:

def pairTermsDepth(depth):   
  yield 0 
  if depth:
      for a in pairTermsDepth(depth-1):
        for b in pairTermsDepth(depth-1):
          yield (a,b)

def pairTerms():
  i=0
  while True:
    for item in pairTermsDepth(i):
      i+=1
      yield item

但这有一个缺点,即当达到新的 while 迭代并耗尽堆栈时,会重新列出所有旧术语。

注意:我不太清楚如何标记这个问题,请随意更改它们。

最佳答案

下面的方法可以在我的电脑半分钟内找到前1亿个词条(打印出来会花更长的时间),生成前N个词条的内存占用是O (平方(N))

def pair_terms() :
    yield 0

    # By delaying this recursion until after a yield, we avoid
    # an infinite recursive loop.
    generated = []
    generator = pair_terms()
    this = generator.next()

    while True:
        for j in range(len(generated)):
            yield (this, generated[j])
            yield (generated[j], this)
        yield (this, this)
        generated.append(this)
        this = generator.next()

诀窍在于,要生成第 n 个项,我只需要保留不超过 sqrt(n) 的项记录。我通过让生成器递归调用自身来做到这一点。这似乎是额外的工作,但由于您只进行了 O(sqrt(n)) 递归调用,因此与生成结果相比,递归调用的开销是一个舍入误差。

关于Python如何生成所有对项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296453/

相关文章:

python - 如何添加 Kivy 目录以便 Sublime Text 可以使用 Kivy 语言进行编译?

python - 在 Google App Engine 中,我不应该在模型中使用实例方法吗?

python - 使用 Selenium 玩 2048

algorithm - 获取给定数字的所有可能组合以达到给定总和

sql - 总结停止时间数据的更好方法?

python - 持续检测到 Django 1.7.2 迁移更改

java - 四色图定理递归回溯算法

python - python 生成器的不一致行为

python - 从 Python 列表中获取前 n 个唯一元素

python - 如何创建正确垃圾收集的自定义生成器类