Python递归生成器

时间:2016-01-26 13:41:23

标签: python recursion generator yield

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

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]]

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

这就是我现在所拥有的:

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

2 个答案:

答案 0 :(得分: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)]

答案 1 :(得分: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