python-list变量在递归中未存储正确的结果
我试图通过递归存储列表中所有可能的括号 示例:python-list变量在递归中未存储正确的结果,python,list,recursion,Python,List,Recursion,我试图通过递归存储列表中所有可能的括号 示例:printRange(0,3) 答案将是[[0]、[1]、[2]]、[[0]、[1,2]]、[[0,1]、[2]]、[[0,1,2]] 当我尝试在函数中打印结果时,我可以得到正确的答案。当我尝试存储结果并在没有得到所需结果后打印结果时 代码如下: res=[] def printRange(st,size,cans=[]): if(st==size): res.append([]+cans) print c
printRange(0,3)
答案将是[[0]、[1]、[2]]、[[0]、[1,2]]、[[0,1]、[2]]、[[0,1,2]]
当我尝试在函数中打印结果时,我可以得到正确的答案。当我尝试存储结果并在没有得到所需结果后打印结果时
代码如下:
res=[]
def printRange(st,size,cans=[]):
if(st==size):
res.append([]+cans)
print cans
l=[]
for i in range(st,size):
l.append(i)
tmp=[]+cans
tmp.append(l)
printRange(i+1,size,[]+tmp)
printRange(0,3)
print res
当我运行上述代码时,我得到:
[[0], [1], [2]]
[[0], [1, 2]]
[[0, 1], [2]]
[[0, 1, 2]]
[[[0, 1, 2], [1, 2], [2]], [[0, 1, 2], [1, 2]], [[0, 1, 2], [2]], [[0, 1, 2]]]
为什么res变量没有存储预期结果?发生这种情况是因为
cans
是一个列表列表,而这些内部列表会发生变化。您需要在res
中附加一份cans
的深度副本,即制作内部列表副本的副本。您可以使用copy
模块中的deepcopy
来实现这一点,也可以编写一个简单的deepcopy,用于列表列表
这是您的代码的修复版本
#from copy import deepcopy
def deepcopy(list2d):
return [u[:] for u in list2d]
res = []
def printRange(st, size, cans=[]):
if(st == size):
res.append(deepcopy(cans))
print cans
l = []
for i in range(st, size):
l.append(i)
tmp = [] + cans
tmp.append(l)
printRange(i+1, size, tmp)
printRange(0, 4)
print res
输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
请注意,使用列表或其他可变对象作为默认参数通常不是一个好主意,因为默认参数是在定义函数时指定的,而不是在调用函数时指定的,这可能会导致意外行为。它实际上不会给您的代码带来问题,但最好避免使用默认的可变参数,除非您需要这种“有趣”的行为,例如,它可以用作备忘录缓存,即使这样,您也应该使用注释来解释您是有意这样做的。:)有关更多详细信息,请参阅
我会以一种稍微不同的方式来完成这项任务,使用我最喜欢的“玩具”之一:递归 输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
如果您确实想要一个包含所有结果的列表,只需将生成器传递给列表
构造函数:
res = list(brackets(2))
print res
输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
之所以会发生这种情况,是因为
cans
是一个列表列表,而这些内部列表会发生变化。您需要在res
中附加一份cans
的深度副本,即制作内部列表副本的副本。您可以使用copy
模块中的deepcopy
来实现这一点,也可以编写一个简单的deepcopy,用于列表列表
这是您的代码的修复版本
#from copy import deepcopy
def deepcopy(list2d):
return [u[:] for u in list2d]
res = []
def printRange(st, size, cans=[]):
if(st == size):
res.append(deepcopy(cans))
print cans
l = []
for i in range(st, size):
l.append(i)
tmp = [] + cans
tmp.append(l)
printRange(i+1, size, tmp)
printRange(0, 4)
print res
输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
请注意,使用列表或其他可变对象作为默认参数通常不是一个好主意,因为默认参数是在定义函数时指定的,而不是在调用函数时指定的,这可能会导致意外行为。它实际上不会给您的代码带来问题,但最好避免使用默认的可变参数,除非您需要这种“有趣”的行为,例如,它可以用作备忘录缓存,即使这样,您也应该使用注释来解释您是有意这样做的。:)有关更多详细信息,请参阅
我会以一种稍微不同的方式来完成这项任务,使用我最喜欢的“玩具”之一:递归 输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
如果您确实想要一个包含所有结果的列表,只需将生成器传递给列表
构造函数:
res = list(brackets(2))
print res
输出
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2], [3]], [[0], [1], [2, 3]], [[0], [1, 2], [3]], [[0], [1, 2, 3]], [[0, 1], [2], [3]], [[0, 1], [2, 3]], [[0, 1, 2], [3]], [[0, 1, 2, 3]]]
[[0], [1], [2], [3]]
[[0], [1], [2, 3]]
[[0], [1, 2], [3]]
[[0], [1, 2, 3]]
[[0, 1], [2], [3]]
[[0, 1], [2, 3]]
[[0, 1, 2], [3]]
[[0, 1, 2, 3]]
[[[0], [1], [2]], [[0], [1, 2]], [[0, 1], [2]], [[0, 1, 2]]]
顺便说一句,代码中使用的技术称为。您可能还对此相关问题感兴趣。顺便说一句,代码中使用的技术称为。您也可能对此相关问题感兴趣