2017-09-13 129 views
-4

对于一些算法,我发现它方便地定义递归函数,看起来是这样的:循环递归函数

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进行计数。我不明白为什么Python会这样做。

我的(含糊不清)问题是为什么Python这样做,是否有一些明显的修改我的代码,会给我最初的预期输出?

+2

你永远不会改变'l',它从'len(l)== 1'开始,这意味着它打印两次并存在:你的'else'永远不会被触发。 – TemporalWolf

+0

输入“[0]”如何导致你描述的输出?请[编辑]你的问题,包括[mcve]。 – TemporalWolf

+0

@Keiwan任何有效的输入(一个列表)可能会提供给该函数,它会输出上述或提供的列表两次,然后是一个0,然后是一个1。我怀疑这不是他的意图。 – TemporalWolf

回答

1

你的代码永远不会递归。通过for

for i in range(2): 
    if len([0])>=1: 
     print([0]+[i]) 
    else: 
     return f([0]+[i]) 
# de-functified 

第一次,len([0]) >= 1True,所以它打印[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 
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.您在这两个时间通过循环获取的“true”分支。请注意,你永远不会更改列表l。因此,你永远不会做出你期望的递归调用。

REPAIR

我不能修复这个给你,因为你没有解释逻辑您的期望背后L [0]将变为1。你从来没有分配给该元素,也不会通过全对象分配或递归调用的参数来重建l