Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何将递归函数转换为生成器?_Python_Python 2.7_Recursion_Generator - Fatal编程技术网

Python 如何将递归函数转换为生成器?

Python 如何将递归函数转换为生成器?,python,python-2.7,recursion,generator,Python,Python 2.7,Recursion,Generator,我使用以下递归函数为(命名)位置列表生成有效配置列表,其中每个位置只能使用一次: def generate_configurations(configurations, named_positions, current): if len(current) == len(named_positions): configurations.append(current) return configurations name, positions = n

我使用以下递归函数为(命名)位置列表生成有效配置列表,其中每个位置只能使用一次:

def generate_configurations(configurations, named_positions, current):
    if len(current) == len(named_positions):
        configurations.append(current)
        return configurations

    name, positions = named_positions[len(current)]
    for x in positions:
        if x not in current:
            generate_configurations(configurations, named_positions, current + (x,))

    return configurations
下面是我如何称呼它的一个例子:

named_positions = [('a', [0,1,2]),
                   ('b', [1,3]),
                   ('c', [1,2])]

for comb in generate_configurations([], named_positions, ()):
    print comb
这将提供以下输出:

(0, 1, 2)
(0, 3, 1)
(0, 3, 2)
(1, 3, 2)
(2, 3, 1)
此外,可能没有有效的组合,例如,
命名的_位置=[('a',[3]),('b',[3])]

现在,根据输入的
命名的\u位置
配置
列表可能会迅速变大,从而产生
内存错误
。我相信这个函数可以作为生成器重新编写,所以我尝试了以下方法:

def generate_configurations(named_positions, current):
    if len(current) == len(named_positions):
        yield current

    name, positions = named_positions[len(current)]
    for x in positions:
        if x not in current:
            generate_configurations(named_positions, current + (x,))

named_positions = [('a', [0,1,2]),
                   ('b', [1,3]),
                   ('c', [1,2])]

for comb in generate_configurations(named_positions, ()):
    print comb

但这根本不会产生任何结果。我做错了什么?

您需要
产生
递归调用堆栈,或者内部
产生
永远不会发生并被丢弃。由于这被标记为Python 2.7,递归调用将通过更改以下内容来处理:

if x not in current:
    # Creates the generator, but doesn't run it out to get and yield values
    generate_configurations(named_positions, current + (x,))
致:

在Python 3.3及更高版本中,您可以通过以下方式直接委派:

if x not in current:
    yield from generate_configurations(named_positions, current + (x,)):

使用生成器时,需要确保子生成器递归调用传回调用方法

def recur_generator(n):
    yield my_thing
    yield my_other_thing
    if n > 0:
        yield from recur_generator(n-1)
请注意,这里的
yield from
将yield调用传递回父调用

您应该将递归调用行更改为

yield from generate_configurations(named_positions, current + (x,))
否则,您的发电机就正常了

编辑:没有注意到这是python2。你可以用

for x in recur_generator(n-1):
    yield x

谢谢,现在可以了-我还必须在
yield current
之后添加一个
return
语句,以避免它再次出现。
for x in recur_generator(n-1):
    yield x