遞歸
在函數內部,可以調用其他函數;
如果一個函數在內部調用自身本身,這個函數就是遞歸函數。
例如,我們來計算階乘:
n! = 1 x 2 x 3 x ... x n,
用函數f1(n)表示,可以看出:
f1(n) = n! = 1 x 2 x 3 x ... x (n-1) x n
= (n-1)! x n = f1(n-1) x n
所以,f1(n)可以表示為 n x f1(n-1),只有n=1時需要特殊處理。
於是,f1(n)用遞歸的方式寫出來就是:
def f1(n):
if n==1:
return 1
return n * f1(n - 1)
上面就是一個遞歸函數。執行結果如下:
>>> f1(1)
1
>>> f1(3)
6
>>> f1(10)
3628800
那么,利用函數編寫如下數列:
斐波那契數列指的是這樣一個數列
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,
610,987,1597,2584,4181,6765,10946,17711,28657,46368 ...
實現代碼如下:
def func(arg1,arg2):
if arg1 == 0:
print arg1, arg2
arg3 = arg1 + arg2
print arg3
func(arg2, arg3)
func(0,1)
執行結果如下:(“....”代表省略)
.....
26863810024485359386146727202142923967616609318986952340123175997617981700247881689338369654483356564191827856161443356312976673642210350324634850410377680367334151172899169723197082763985615764450078474174626
Traceback (most recent call last):
.....
334151172899169723197082763985615764450078474174626
Traceback (most recent call last):
File "<stdin>", line 1, in <module> #有報錯
......
為什么上面有報錯,難道是程序錯了?其實不是,程序沒錯,因為“斐波那契數” 規律是前兩個數相加
等於后面一個數,而程序一直不斷這樣執行下去,最終達到系統默認臨界值,當然程序也就出錯了
接下來,我們把程序再改改,我們讓“不斷循環的第三個值”(即arg3)大於1000的時候 返回一個值,
看看這個時候的效果,直接看下面代碼:
def func1(arg1,arg2):
if arg1 == 0:
#print arg1,arg2
pass
arg3 = arg1 + arg2
if arg3 > 1000:
return arg3
func1(arg2,arg3)
result = func1(0,1)
print result
你們覺得上面打印的結果是什么?
看下面執行結果:
>>> print result
None
這是為什么,苦苦熬了這么多年,終於等到你,>~< ...(哈哈,開個玩笑)
上面代碼分解如下:
def func1(arg1,arg2):
#arg1 = 0 ,arg2 = 1,第2次:arg1 = 1,arg2 = 1,第3次:arg1 = 1,arg2 = 2,
第4次:arg1 = 2,arg2 = 3,
if arg1 == 0: #滿足條件,開始執行
#print arg1,arg2
pass #不做任何處理
arg3 = arg1 + arg2 #走到這一步,arg3 = 0 + 1 = 1,第2次:arg3 = 1 + 1 = 2,
第3次,arg3 = 1 + 2 = 3,第4次:arg3 = 2 + 3 = 5, .... 執行到第18次....
if arg3 > 1000: #第一次循環不符合條件,繞開return arg3,而繼續往下執行;....
假設執行到第18次時符合條件,那么就會執行下面的代碼,即 return arg3 會被執行!!!
return arg3
#第一次循環不執行,2,3,4次都一樣不執行;.....,假設第18次時符合條件,並且執行
了return arg3,重點來了!!!!,這個時候我們都知道,函數體中,一個值被return,
那么這個函數的生命周期也就結束,不再往下執行,也就意味着下面的func1(arg2,arg3)
沒有被執行.
func1(arg2,arg3)
#自身調用第2個和第3個的值,即第1次為:1 ,1 第2次為1,2,第3次:2,3 第4次:3,5 ....
假設執行到第18次,這個時候沒有被執行,因為上面return的出現,函數生命周期已經結束
(重點!!:分析:既然18次時符合條件,並且return arg3,函數直接出去了,大家不妨想想,
那么在出去之前,它的上一次執行,也就是第17次並沒有在func1(arg2,arg3)這一步,將這個
函數的值return(返回)給func1(arg1,arg2),也就意味着,17次沒有返回,而18次時,
函數生命周期也已經結束!之后執行函數外面的操作,result = func1(arg1,arg2),print result,
接着往下看:
大家都知道,如果要將一個函數賦值給一個變量,假設這么賦值:result = func1(“值”,“值”),
那么這個函數肯定會有一個返回值,同時賦值給這個變量,由於17次沒有return func1(arg2,
arg3)給func1(arg1,arg2),18次時函數結束,那么這個函數的默認返回值就是None(即空值)
那么賦值給這個變量和打印這個變量也就是None
同時大家記住一句話:python 函數默認是從上往下執行
result = func1(0,1) #第一次開始執行,賦值!第18次賦值,這個時候是None
print result #第1,2,3,4都不執行,因為這個是在函數外,只有函數結束后才行,....
第18次,這里打印了最終值"None"
大家是否已經知道
上面的代碼改成下面這樣:
def func1(arg1,arg2):
if arg1 == 0:
#print arg1,arg2
pass
arg3 = arg1 + arg2
if arg3 > 1000:
return arg3
return func1(arg2,arg3) #這里return ,所有有值
執行結果如下:
>>> result = func1(0,1)
>>> print result
1597
return 返回值(經典例子):
你們認為下面的result 結果是什么? 10000???NO,NO,NO
def n4():
return "10000"
def n3():
n4()
def n2():
n3()
def n1():
n2()
result = n1()
print result
返回值為None
為什么?
請聽分解:當我們最終print result 時,result = n1(), n1函數調用n2, n2函數調用n3,
n3函數調用n4,而當n3調用n4時,(n4函數有返回值),並沒有return n4(),意味着n3是None,
因此n2函數在調用n3時,由於n3是None,,同時n3本身也沒有return給n2,(就算return給n2了,
也是None,哈哈)所以最終返回就是None
這個例子是不是很經典?好了,今天很晚了,就分享到這里,因為白天上班,沒什么時間寫,也就只能晚上
寫了(ps,現在是凌晨2點18分),下次繼續新的內容!