我遇到了一个带有递归函数调用的循环,其中循环的起始范围递增如下。代码输出如下序列。但是,我无法概念化生成此特定序列的原因。有人可以对其工作有所了解。将这个递归函数转换为输出相同序列的迭代函数是多么可行。请帮忙。
代码:
def foo(step=0):
for i in range(step, 4):
print step
foo(step+1)
foo()
输出:
0 1 2 3 2 3 1 2 3 2 3 1 2 3 2 3 0 1 2 3 2 3 1 2 3 2 3 1 2 3 2 3 0 1 2 3 2 3 1 2 3 2 3 1 2 3 2 3 0 1 2 3 2 3 1 2 3 2 3 1 2 3 2 3
寻找Anagrams的类似设计代码:
def find_anagrams(word, step=0):
print 'step->', step
if step == len(word):
print "".join(word)
for i in range(step, len(word)):
print step, i
word_ = list(word)
word_[step], word_[i] = word_[i], word_[step]
find_anagrams(word_, step+1)
答案 0 :(得分:2)
让我试试:
从你的代码片段,在每个函数调用中,即foo(步骤+ 1)一个称为激活记录的结构或 创建框架以存储有关该函数调用进度的信息。 因此,当一个函数的执行导致嵌套函数调用时,执行前一个调用 被暂停,其激活记录将该位置存储在控制流程的源代码中 应该在返回嵌套调用时继续。
以下是主要内容:
当步骤== 4,其中轮流范围(4,4)==空列表时,该时间迭代将不会发生,因此它将返回 没有。然后它将移动到前一帧,它停止并开始一个新的迭代和递归函数调用 直到范围(4,4)。
注意:递归基本情况仅在步骤== 4,该时间范围(4,4)并返回无。
每次重复都需要一个基本案例,否则它会转到无限循环。
所以,让我们看一下递归跟踪:我正在添加i
来区分step
和迭代增量。
# 1 def foo(step=0):
# 2 for i in range(step, 4):
# 3 print 'i: %d, step: %d' % (i,step)
# 4 foo(step+1)
# 5 foo()
line 5
line 1 foo with step=0 which is default
line 2 range(0,4) Frame: A, 0 is over, next=1
line 3 step = 0 Output: i: 0, step: 0
line 4 calling foo(0 + 1)
line 1 foo with step=1
line 2 range(1,4) Frame: B, 1 is over, next=2
line 3 step = 1 Output: i: 1, step: 1
line 4 calling foo(1 + 1)
line 1 foo with step=2
line 2 range(2,4) Frame: C, 2 is over, next=3
line 3 step = 2 Output: i: 2, step: 2
line 4 calling foo(2 + 1)
line 1 foo with step=3
line 2 range(3,4) Frame: D, 3 is over, next=4
line 3 step = 3, Output: i: 3, step: 3
line 4 calling foo(3 + 1)
line 1 foo with step=4
line 2 range(4,4) Frame: E,
This is an empty list, so it won't come inside the loop, so return None.
Come back to previous Frame: D, i=3 was used, now increment to 4. So, again range(4,4)
line 2 range(4,4) Empty list, from Frame: D, return None
Come back to previous Frame C, now i=3, step was called with value 2
line 2 range(2,4)
line 3 step = 2 Output: i: 3, step: 2, why step == 2 because the function foo was called with step=2
line 4 calling foo(2 + 1)
line 1 foo with step=3
line 2 range(3,4)
line 3 step = 3, Output : i: 3, step: 3
line 4 calling foo(3 + 1)
line 1 foo with step=4
line 2 range(4,4) Empty list again, not going inside the list, return None
line 2 range(2,4) From Frame: B, step was == 1, because the function foo was called with step=1
line 3 step: 1 Output: i: 2, step: 1, here i ==2, because this is the second iteration of Frame B.
line 4 calling foo(1 + 1)
line 1 foo with step=2
line 2 range(2,4)
line 3 step: 2 Output: i: 2, step: 2
在此之后它遵循相同的递归方式,直到迭代范围被推,即范围(4,4)
如果有帮助,请告诉我。
答案 1 :(得分:0)
我认为你的anagram代码可以通过使用stdlib来重构,避免递归循环:
from itertools import permutations
def anagrams (word):
anagrams = set ()
for p in permutations (word):
anagram = ''.join (p)
anagrams |= {anagram}
return anagrams
def isAnagram (word1, word2):
return sorted (word1) == sorted (word2)
答案 2 :(得分:-1)
考虑for循环。您正在遍历range(step, 4)
。如果step = 0
,那么您正在迭代[0,1,2,3]
,如果是step = 1
,那么您正在迭代[1,2,3]
,依此类推。
每次调用foo(step)
时,它会迭代该范围 - 但在当前调用中迭代的范围不会更改。因此,对于第一个循环,您将获得从0到3的迭代,第二个循环是1-3,等等。
为什么这样打印?观察。
for i in range(0,4):
print 0
for j in range(1,4):
print 1
for k in range(2,4):
print 2
for h in range(3,4):
print 3
这将与递归函数
具有相同的输出