標籤:== 方式 result 匿名函數 int map print語句 賦值 方向
嵌套函數:
1. 函數內部可以再定義函數
2. 函數只有被調用之後才會執行
看如下代碼:
age = 18def func1(): age = 22 print(age) def func2(): age = 28 # 如果這個age沒有被賦值,它會先向它的父級(func1)裡面找,如果父級也沒有就再向它的爺爺級(全域的age)找。 # 一層一層由內向外找 print(age) func2()func1()# 輸出結果:#22#28
註: 函數內部的變數都叫局部變數,只不過局部變數之間也有等級關係
#情景1:age = 18def func1(): def func2(): print(age) age = 22 # age=22 依然是func1裡面的變數 func2() #程式從上到下運行到這一步的時候 age已經在函數內被賦值為22func1()#輸出結果:# 22#情景2:age = 18def func1(): def func2(): print(age) func2() #程式由上到下運行到這一步時,由於func2中沒有age,func2會向上一級找,找到了func1中的age=22,但由於變數需要先定義後使用(定於放在使用前面),所以程式會報錯。例如情景3 age = 22 # age =22依然是函數func1裡面的變數func1()# 輸出結果會報錯。#情景3:age = 18def func1(): def func2(): print(age2) func2() age2 = 22func1()# 輸出結果會報錯。#情景4:age = 18def func1(): global age #程式執行到這一步的時候,age已經被聲明成了全域變數,並被賦值為18 def func2(): print(age) #執行到這一步的時候age直接調用age這個全域變數 func2() age = 22 # 程式執行到這一步的時候age這個全域變數又被賦值成了22func1()print(age)# 輸出結果:# 18# 22#情景5:age = 18def func1(): global age #到這一步age被聲明成全域變數,並且此時的值還是18 age = 22 # 到這一步時age又被重新賦值為22 def func2(): print(age) func2() func1()#輸出結果:# 22#情景6:age = 18def func1(): global age #執行到這一步是age還是18 def func2(): print(age) #執行到這一步的時候age已經是22了 age = 22 # age這個全域變數 在func2調用之前又被改成了22 func2()func1()# 輸出結果:# 22
註:這幾種情況用於分析,實際生產中很少用。
範圍:
在Python中一個函數的就是一個範圍,局部變數其實是放在它的範圍中
age = 18def func1(): age = 22 def func2(): print(age) return func2 #func2沒加括弧,返回的是這個函數名val= func1()print(val) #列印的是函數名val() #val就是func2, 此時會執行# 輸出結果:# <function func1.<locals>.func2 at 0x0000009F6AEAB9D8># 22 #雖然是在外部執行,但依然是通過其定義域的關係去調用,所以不會是18.
代碼定義完成後,範圍就已經產生。以後調用時會通過其定義域關係向上尋找(不管這個函數名是在哪裡被調用,只要一執行,它還是會回來它定義的地方向上去尋找。)。
匿名函數:
普通函數:
def calc( x,y):
return x*y
匿名函數: lambda x,y: x*y #聲明一個匿名函數 (把多行語句變成一行)
調用:
func = lambda x,y: x*y
func(3,8)
匿名函數最複雜的也只能進行三元運算。
匿名函數通常跟其他的方法搭配使用,作用主要是節省代碼量、如:
# 要求: 使range(10)裡面的數各自跟自己相乘data = list(range(10))print(list(map(lambda x:x*x,data)))# 輸出結果:# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]# map的用法: map(func, *iterables) --> map object# 就是把iterables中的每一個值都進行一下前面的函數。# list(map())的作用是讓map的結果變成列表的樣子# iterables有:list,str,tuple,dict,file,xrange等
高階函數:
變數可以指向函數,函數的參數能夠接收變數,一個函數可以接收另一個函數作為參數,這種函數就叫高階函數。
另外,一個函數return了另外一個函數,這個也是高階函數,如:
def func(x,y): return abs,x,yres = func(3,-10)# func也是高階函數# abs是求絕對值的函數,用法:abs( 數字)# 函數返回多個值的時候,是以元祖形式返回的
總結:
只需滿足以下一個條件即為高階函數:
1. 接收一個或多個函數作為輸入
2. return返回另一個函數
遞迴函式:
如果一個函數在其內部調用了它自己,這樣的函數就是遞迴函式。 如:讓10除以2,直到為0.
a= 10def calc(n): n = int(n/2) print(n) if n >0: calc(n) #在函數內部調用它自己,就會產生迴圈calc(a)# 輸出結果:# 5# 2# 1# 0## 而且,程式在結束退出的時候,是從內向外、一層一層逐漸結束的。測試:a= 10def calc(n): n = int(n/2) print(n) if n >0: #這一步的代碼運行分析:第1次print的n是5,由於5>0,n直接進入calc(n),由於calc(n)調用了它自己,就沒有再走下面的print(‘程式退出測試:’,n)這一步,而是又返回上面去進行n=int(n/2)這幾步。n是2和1的時候也是同樣的道理。 calc(n) print(‘程式退出測試:‘,n) # 列印結果分析:最後一輪迴圈n的值是0,此時n==0不再進行calc(n),而是去運行下面的print(‘程式退出測試:’,n)這一步,此時最裡面的這一層迴圈結束;然而上一步n==1時,程式是直接進入了if語句進行了calc(n),並沒有進行下面的print語句,所以當最裡面的n==0這層程式走完之後,n==1也要走完這個print語句。同理,n==2和5時也要依次走這個print語句。
calc(a)# 輸出結果:# 5# 2# 1# 0# 程式退出測試: 0# 程式退出測試: 1# 程式退出測試: 2# 程式退出測試: 5
遞迴函式傳回值:
在遞迴函式的外面得到傳回值是最外層的函數return回來的,想要得到遞迴函式的傳回值,需要在遞迴函式內部每次調用時都要有return值,只有這樣最內層的return值才能通過一層層的return返回到最外層。它的書寫方式是:
if 條件成立:
return 調用自己
else:
return 最裡面的值
例如下面兩個例子:
例子1: 100除以2三次,函數外部得到傳回值。a = 100def func(n,count): if count < 3: return func(n/2,count+1) else: return nresult = func(a,0)print(result)# 輸出結果:# 12.5例子2: 求3的階乘,函數外部得到傳回值。def f(n): if n > 1: return n*f(n-1) else: return nprint(f(3))# 輸出結果:# 6
下面用流程圖說明它們的傳回值是怎麼得到的:
1. 3的階乘:
2. 100除以2三次:
python函數基礎:嵌套函數、範圍、匿名函數、遞迴函式