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