对于某些算法,我发现定义一个如下所示的递归函数很方便:
def f(l):
for i in range(2):
if len(l)>=1:
print(l+[i])
else:
return f(l+[i])
f([0])
但这种行为与我的预期不同。它的作用是打印
[0, 0]
[0, 1]
但我希望它能打印
[0,0]
[0,1]
[1,0]
[1,1]
不知何故,嵌套函数可以访问变量i,而不是使用一些不同的变量启动一个新循环,它只是继续使用这个变量i进行计数。我不明白为什么Python会这样做。
因此,我的(模糊)问题是为什么Python会这样做,并且对我的代码有一些明显的修改会给出我最初期望的输出吗?
答案 0 :(得分:1)
你的代码永远不会泄密。
for i in range(2):
if len([0])>=1:
print([0]+[i])
else:
return f([0]+[i])
# de-functified
首次通过for
循环,len([0]) >= 1
为True
,因此会打印[0] + [0]
。第二次通过for
循环,len([0]) >= 1
仍为True
,因此会打印[0] + [1]
。然后循环结束并且控制在函数外部传递。你永远不会达到你的递归案例(len(l) < 1
)
请注意,您的预期结果只是:
import itertools
result = itertools.product(range(2), repeat=2) # cast to list if necessary
答案 1 :(得分:0)
<强>调试强>
让我们进行一些调试跟踪:
def f(l):
print ("ENTER:", l)
for i in range(2):
print("i=", i, "len(l)=", len(l))
if len(l)>=1:
print(l+[i])
else:
return f(l+[i])
print(f([0]))
输出:
ENTER: [0]
i= 0 len(l)= 1
[0, 0]
i= 1 len(l)= 1
[0, 1]
None
<强>分析强>
使用单元素列表调用该函数。因此, len(l)为1.您通过循环两次取 if 的“true”分支。请注意,您永远不会更改列表 l 。因此,您永远不会进行您期望的递归调用。
<强> REPAIR 强>
我无法解决这个问题,因为你没有解释你期望 l [0] 会变为1的逻辑。你永远不会分配给那个元素,你也不会通过整个对象赋值或递归调用的参数重构 l 。