定義函數: 過程:就是沒有返回值的函數 函數的參數: 形參:只有在被調用時才分配記憶體單元,在調用結束時,即刻釋放所分配的記憶體單元。因此,形參只在函數內部有效。 實參:可以是常量、變數、表達式、函數等,在進行函數調用時,都必須有確定的值,以便把這些值傳給形參。 全局變數和局部變數: 在子程式中定義的變 ...
定義函數:
#語法 def 函數名(參數1,參數2,參數3,...): '''註釋''' 函數體 return 返回的值 #函數名要能反映其意義
過程:就是沒有返回值的函數
函數的參數:
- 形參:只有在被調用時才分配記憶體單元,在調用結束時,即刻釋放所分配的記憶體單元。因此,形參只在函數內部有效。
- 實參:可以是常量、變數、表達式、函數等,在進行函數調用時,都必須有確定的值,以便把這些值傳給形參。
def test(x,y,z): #x=1,y=2,z=3 print(x) print(y) print(z) #位置參數,必須一一對應,缺一不行多一也不行 test(1,2,3) #關鍵字參數,無須一一對應,缺一不行多一也不行 test(y=1,x=2,z=3) #輸出結果: 1 2 3 2 1 3
#參數組:**字典 *列表 def test(x,*args,**kwargs): print(x) print(args,args[-1]) print(kwargs,kwargs.get('s')) test(1,*[1,2,3],**{'s':1}) #輸出結果: 1 (1, 2, 3) 3 {'s': 1} 1
全局變數和局部變數:
在子程式中定義的變數稱為局部變數,在程式的一開始定義的變數稱為全局變數。
全局變數作用域是整個程式,局部變數作用域是定義該變數的子程式。 當全局變數與局部變數同名時:在定義局部變數的子程式內,局部變數起作用;在其它地方全局變數起作用。name='reese' def change_name(): print('我的名字',name) change_name() def change_name(): name='帥' print('我的名字',name) change_name() print(name) def change_name(): global name name='帥' print('我的名字',name) change_name() print(name) #輸出結果: 我的名字 reese 我的名字 帥 reese 我的名字 帥 帥
# 如果函數內部無global關鍵字,優先讀取局部變數,能讀取全局變數,無法對全局變數重新賦值;
但對於可變類型(除數字、字元串、元祖,其他都可變),可對內部元素進行操作。
# 如果函數內部有global關鍵字,變數本質上是全局變數,可讀取可賦值。
# 一般全局變數名用大寫,局部變數名用小寫。
遞歸
#遞歸調用 def calc(n): print(n) if int(n / 2) == 0: return n s = calc(int(n / 2)) return s calc(10) #輸出: 10 5 2 1
遞歸特性:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
3. 遞歸效率不高,遞歸層次過多會導致棧溢出(在電腦中,函數調用是通過棧(stack)這種數據結構實現的,
每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)
#問路 import time person_list=['林克','士官長','奎爺','但丁'] def ask_way(person_list): print('-'*60) if len(person_list) == 0: return '沒人知道' person=person_list.pop(0) if person == '但丁': return '%s說:我知道,路在腳下,走多了,也就知道了' %person print('hi 美男[%s],敢問路在何方' %person) print('%s回答道:我不知道,但念你慧眼識豬,你等著,我幫你問問%s...' %(person,person_list)) time.sleep(3) res=ask_way(person_list) # print('%s問的結果是: %res' %(person,res)) return res res=ask_way(person_list) print(res)
函數作用域
作用域在定義函數時就已經固定住了,不會隨著調用位置的改變而改變
name = "reese" def s(): name = "neo" def n(): print(name) return n func = s() func() #輸出: neo
匿名函數:
不需要顯示的指定函數
def calc(x): return x + 10 res = calc(10) print(res) #輸出: 20 #用匿名函數: func = lambda x: x + 10 print(func(10)) #輸出: 20
func = lambda x, y, z: x + y + z print(func(1, 2, 3)) #輸出: 6
map函數:
num = [3, 4, 5, 6, 11, 7, 54] #lambda x:x+1 def add_one(x): #列表元素自增一 return x + 1 #lambda x:x-1 def minus_one(x): #列表元素自減一 return x - 1 def map_test(func, array): ret = [] for i in num: res = func(i) ret.append(res) return ret print(map_test(add_one,num)) # print(map_test(lambda x:x+1,num)) #可用匿名函數 print(map_test(minus_one,num)) # print(map_test(lambda x:x-1,num)) #終極版本 def map_test(func,array): ret = [] for i in array: res = func(i) ret.append(res) return ret print(map_test(lambda x:x+1,num)) #輸出結果: [4, 5, 6, 7, 12, 8, 55] [2, 3, 4, 5, 10, 6, 53] [4, 5, 6, 7, 12, 8, 55]
map:
處理序列中的每個元素,得到的結果是一個列表,該列表元素個數及位置與原來一樣
num = [3, 4, 5, 6, 11, 7, 54] res=map(lambda x:x+1,num) print('內置函數map,處理結果',list(res)) print(list(map(minus_one,num))) msg = "reese" print(list(map(lambda x:x.upper(),msg))) #輸出結果: 內置函數map,處理結果 [4, 5, 6, 7, 12, 8, 55] [2, 3, 4, 5, 10, 6, 53] ['R', 'E', 'E', 'S', 'E']
filter函數:
便利序列中的每個元素,判斷每個元素得到布爾值,如果是True則留下來
people = ['reese', 'neo_s', '林克'] print(filter(lambda n: not n.endswith('s'), people)) res = filter(lambda n: not n.endswith('s'), people) print(list(res)) print(list(filter(lambda n: not n.endswith('s'), people))) #輸出: <filter object at 0x04E612B0> ['reese', '林克'] ['reese', '林克']
reduce函數:
處理一個序列,然後把序列進行合併操作
# reduce函數 from functools import reduce num = [1, 2, 3, 4, 5] print(reduce(lambda x, y: x + y, num, )) #輸出: 15