2016-09-07 64 views
1

在理解字符串排列及其在python中的實現(關於this post)時,我偶然發現了使用range()for循環中的某些內容,我只是不明白。Python - 範圍()在遞歸時變異變量值嗎?

看看下面的代碼:

def recursion(step=0): 
    print "Step I: {}".format(step) 
    for i in range(step, 2): 
     print "Step II: {}".format(step) 
     print "Value i: {}".format(i) 

     print "Call recursion" 
     print "\n-----------------\n" 

     recursion(step + 1) 

recursion() 

這讓下面的輸出:

[email protected]:~# python range_test.py 

Step I: 0 
Step II: 0 
Value i: 0 
Call recursion 

----------------- 

Step I: 1 
Step II: 1 
Value i: 1 
Call recursion 

----------------- 

Step I: 2 
Step II: 0 <---- WHAT THE HECK? 
Value i: 1 
Call recursion 

----------------- 

Step I: 1 
Step II: 1 
Value i: 1 
Call recursion 

----------------- 

Step I: 2 
[email protected]:~# 

正如你可以看到變量step使用range()一定for循環運行後得到一個新值 - 見標記WHAT THE HECK

任何想法來解除霧?

+3

'range(2,2)'爲空。它不會進入'for'循環。因此,它會打印「Step I:2」,然後返回,帶有'range(1,2)'的前一個函數然後也完成了它的1次迭代,然後您又回到'step'爲0的位置。 –

+0

[ 'itertools.permutations'](https://docs.python.org/2/library/itertools.html#itertools.permutations) – GingerPlusPlus

回答

1

您的結論是不正確step值不會通過使用range更改。 這可以被驗證爲:

def no_recursion(step=0): 
    print "Step I: {}".format(step) 
    for i in range(step, 2): 
     print "Step II: {}".format(step) 
     print "Value i: {}".format(i) 

no_recursion(step=2) 

產生的輸出:

Step I: 2 

它自range(2,2)返回[]預期。

step其值改變爲0來,因爲函數recursion(稱爲與step=2)返回它打印Step I: 2後,則控制返回到功能recursion(稱爲與step=1),它立即返回自for loop已經終止的錯覺,然後控制返回到recursion(調用step=0)繼續,因爲它有1次迭代,並且打印Step II: 0到控制檯,這並不意外。這可以是簡單的,如果我們修改代碼一點點(加入函數入口和出口記錄)來觀察和觀察輸出:

def recursion(step=0): 
    print "recursion called with [step = {}]".format(step) # add entry logging 
    print "Step I: {}".format(step) 
    for i in range(step, 2): 
     print "Step II: {}".format(step) 
     print "Value i: {}".format(i) 

     print "Call recursion" 
     print "\n-----------------\n" 

     recursion(step + 1) 
    print "--> returned recursion [step = {}]".format(step) # add exit logging 

recursion() 

由此代碼生成的輸出是:

recursion called with [step = 0] 
Step I: 0 
Step II: 0 
Value i: 0 
Call recursion 

----------------- 

recursion called with [step = 1] 
Step I: 1 
Step II: 1 
Value i: 1 
Call recursion 

----------------- 

recursion called with [step = 2] 
Step I: 2 
--> returned recursion [step = 2] 
--> returned recursion [step = 1] 
Step II: 0 
Value i: 1 
Call recursion 

----------------- 

recursion called with [step = 1] 
Step I: 1 
Step II: 1 
Value i: 1 
Call recursion 

----------------- 

recursion called with [step = 2] 
Step I: 2 
--> returned recursion [step = 2] 
--> returned recursion [step = 1] 
--> returned recursion [step = 0] 

我們可以清楚地看到遞歸展開的順序,並觀察到step的值在每個步驟中都是一致的。

+0

非常感謝,這是一個非常棒的清晰解釋! –

+0

@RalfMarmorglatt很高興幫助! –