【问题标题】:Python Recursive GeneratorPython 递归生成器
【发布时间】:2016-05-03 02:17:11
【问题描述】:

我正在尝试制作一个递归生成器,但我显然遗漏了一些东西。基本上,我有一个直方图特定维度的正负值列表,并且想要获得正负的每种组合。 例如:

input = [[-1,2],[-3,4],[-5,6]]

而我需要的结果是(虽然我希望它作为生成器而不是列表,但你明白了):

output = [[-1, -3, -5],[-1, -3, 6],[-1, 4, -5],[-1, 4, 6],[2, -3, -5],[2, -3, 6],[2, 4, -5],[2, 4, 6]]

我已经设法完成它,但只能通过将项目附加到我的递归内部的全局列表中,但我真的希望我可以使用生成器来执行此操作并迭代我的函数,因为那样会变得如此之多更清洁的海事组织。

这是我现在拥有的:

def combs(idx,array,current=[]):
    for item in array[idx]:
        current_copy = current[:]
        current_copy.append(item)
        if idx + 1 < len(array):
            combs(idx+1,array,current_copy)
        else:
            print current_copy
            # yield current_copy

这将完全打印出我想要的内容,但是当我尝试将打印更改为 yield 并循环该函数时,它不起作用。 (例如)

for item in combs(0,input,[]):
    print item

【问题讨论】:

  • 请避免使用函数名称(在这种情况下为input)调用变量,这会让您头疼

标签: python recursion generator yield


【解决方案1】:

如果您使用的是 Python 3.3 或更高版本,则需要 yield from 语句:

def combs(idx,array,current=[]):
    for item in array[idx]:
        current_copy = current[:]
        current_copy.append(item)
        if idx + 1 < len(array):
            yield from combs(idx+1,array,current_copy)
        else:
            yield current_copy

在 Python 2.7 上,您可以将 yield from 展开为循环:

def combs(idx,array,current=[]):
    for item in array[idx]:
        current_copy = current[:]
        current_copy.append(item)
        if idx + 1 < len(array):
            for i in combs(idx+1,array,current_copy):
                yield i
        else:
            yield current_copy

【讨论】:

  • 我使用的是 2.7,有没有类似的替代方案?
  • 您应该能够遍历递归的 combs 调用,并产生单独的值
  • 我已经尝试过完全按照上面的操作,除了将 print current_copy 切换为 yield current_copy,我没有得到任何输出。
  • 所以我看到它可以工作,但我很困惑为什么我需要循环递归函数调用,你能解释一下吗?
  • 调用combs 只是给你一个生成器对象,你必须循环它以从中获取值。这不像调用返回值的常规函数​​。 yield from 只是使用可迭代对象(如生成器)并产生值的语法糖。
【解决方案2】:

此任务的另一个选项是itertools.product 函数:

>>> from itertools import product
>>> input = [[-1,2],[-3,4],[-5,6]]
>>> list(product(*input))
[(-1, -3, -5), (-1, -3, 6), (-1, 4, -5), (-1, 4, 6), (2, -3, -5), (2, -3, 6), (2, 4, -5), (2, 4, 6)]

【讨论】:

  • 这很好,解决了手头的整体问题!我仍然很好奇为什么我试图做的事情不起作用:(
  • 如果他想要生成器应该做myGenerator = product(*myInput)
  • @Mr.E 正确,我用list() 来演示结果。
猜你喜欢
  • 2021-05-22
  • 2013-09-16
  • 2013-05-19
  • 2012-05-03
  • 2010-10-25
  • 2021-10-17
  • 2020-11-04
  • 1970-01-01
  • 2017-06-26
相关资源
最近更新 更多