函數(def)
- global:全局變量
- nonlocal:將此變量提升到上一級
函數的作用:
1.減少重復代碼量。
2.可統一維護。
3.可重復調用。
雜貨
單個打印
a,b,c = [1,2,3]
print(a)
print(b)
print(c)
a,*_,e = [1,2,3,4,5,6] #取第一個和最后一個
print(a)
print(e)
函數中return,返回多個值是返回的元祖。
def bar(x,y): '返回值' print('from the bar ...') return 1,2,3,4,5,6,7,[1,2,3,4],{1,2,3,4,5} a,*_,e,f = bar(1,3) #解壓的返回值是一一對應的 print(a) print(e) print(f)
*args **kwargs
第一個是得到的一個元祖,第二個是得到的一個字典
def foo(name,age): #定義一個函數,加上兩個形參 print(name) #打印形參 print(age) def bar(*args,**kwargs): #定義一個函數,這個兩個形參是,位置參數 foo(*args,**kwargs) #調用foo函數,定義兩個實參, bar(1,2) #通過遍歷,解析兩個實參
函數的調用方式
ps.先定義后調用。。。
# #定義好兩個函數 正確的方式 # def foo(): # print('111') # bar() # # def bar(): # print('from the bar') # #------------------------------------- # #在調用 # foo() #定義好兩個函數 錯誤的方式 def foo(): print('111') bar() #調用函數,當函數執行的時候,是先走到foo()函數,bar()是不會執行的 foo() def bar(): print('from the bar')
1.函數的書寫方法:
1 def t(): 2 name = "lt" 3 print("我是誰:",name) 4 t()
函數快捷寫法: # t = lambda x:x+1 # print(t(2))
2.函數嵌套
方法:
def t(): .... def tt(): .... def ttt(): ....
1 def huangwei(): 2 name = '黃偉' 3 print(name) 4 def liuyang(): 5 name = "劉洋" 6 print(name) 7 def nulige(): 8 name = '努力哥' 9 print(name) 10 print(name) 11 nulige() 12 liuyang() 13 print(name) 14 huangwei()
3.函數遞歸
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
3.遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,
函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,
棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,
所以,遞歸調用的次數過多,會導致棧溢出)
1 def calc(n): 2 print(n) 3 if int(n / 2) == 0: 4 return n 5 res=calc(int(n / 2)) 6 return res 7 8 res=calc(10) 9 print(res)
1 import time 2 per = ['lt', 'liu', 'zhang','yang'] 3 def res(per): 4 print('-'*60) 5 if len(per) == 0: 6 return "沒人知道" 7 person = per.pop(0) 8 if person == 'yang': 9 return "%s說:我知道,就在北京市朝陽區" %person 10 print('你好,%s,請問你知道在哪里嗎 ?' %person) 11 print('%s說:我不知道,我可以幫你問問%s...'%(person,per)) 12 time.sleep(3) 13 v = res(per) 14 print('%s問的結果是:%s'%(person,v)) 15 return v 16 v = res(per) 17 print(v)
4.作用域
1 name = 'yang' 2 def foo(): 3 name = 'liu' 4 def bar(): 5 # name = 'li' 6 def tt(): 7 print(name) 8 return tt() 9 return bar 10 r = foo() #bar:這是獲取內存地址 11 r() #這是相當於讀取bar里面的函數,運行tt函數的print
1 name = 'yang' 2 def foo(): 3 name = 'liu' 4 def bar(): 5 # name = 'li' 6 def tt(): 7 print(name) 8 return tt 9 return bar() 10 r = foo() #r:是tt函數的 11 print(r) #讀取tt函數的內存 12 r() #打印tt函數的print
5.匿名函數
1 #函數retrue返回值 2 def res(x): 3 return x+1 4 print(res(10)) 5 6 7 8 #匿名函數 9 name = 'yang' 10 te = lambda x:name+'___' 11 r = te(name) 12 print(r)
6.閉包
#閉包:定義在內部的函數,且引用外部作用域不能引用全局作用域的稱之為閉包
#第一種
def foo(): x = 1 y = 2 def bar(): print(x) y return bar f = foo() f() print(f.__closure__) #查看我閉包內的變量地址, print(f.__closure__[1].cell_contents)#通過下標的方式把我的下標讀取出來
#第二種
def foo(x):
def bar():
print('form the bar')
print(x)
print('form the foo....')
return bar
f = foo(2)
f()
檢測是不是閉包
x =1 def foo(): def bar(): print('form the bar') print(x) print('form the foo....') return bar f = foo() print(f.__closure__) #是不是閉包,可以用.__closure__測試
函數式、面向過程、面向對象
內置函數:
map()
#處理序列中的每個元素,得到的結果是一個‘列表’,該‘列表’元素個數及位置與原來一樣
1 # num = [1,2,5,4,8,6,11,7] 2 # def map_test(func,array): #func:函數 #array:可迭代對象 3 # li = [] 4 # for i in array: 5 # str = func(i) 6 # li.append(str) 7 # return li 8 # print(map_test(lambda x:x+1,num)) 9 10 num = 'yangxiangshishui' 11 # #map():內置函數 12 # print(list(map(lambda x:x*2,num))) 13 res=map(lambda x:x.upper(),num) 14 #只能使用一次 15 print('內置函數map,處理結果',res) 16 # for i in res: 17 # print(i) 18 print(list(res))
filter()
#filter遍歷序列中的每個元素,判斷每個元素得到布爾值,如果是True則留下來
# people=[
# {'name':'alex','age':1000},
# {'name':'wupei','age':10000},
# {'name':'yuanhao','age':9000},
# {'name':'linhaifeng','age':18},
# ]
# print(list(filter(lambda p:p['age']<=18,people)))
函數的用法 # pop = ['li_sb', 'sb_liu_sb', 'sb_zhang_sb', 'yang'] # def re(n): # return n.endswith('sb') # def mo(func,array): # li = [] # for i in array: # if not func(i): # li.append(i) # return li # print(mo(lambda n:n.endswith('sb'),pop)) 使用filter()方法 #filter()內置函數:取反,如需取正需在not # print(list(filter(lambda n:not n.endswith('sb'),pop)))
reduce()
#reduce:處理一個序列,然后把序列進行合並操作
from functools import reduce
print(reduce(lambda x,y:x+y,range(100),100))
print(reduce(lambda x,y:x+y,range(1,101)))
1. # num = [1,5,4,7,6,3] # def nums(array): # li = 0 # for i in array: # li+=i # return li # print(nums(num)) 2. # num = [1,5,2] # def test(x,y): # return x*y # def nums(func,array): # li = array.pop(0) # for i in array: # li=func(i,li) # return li # print(nums(test,num)) 3. # num = [2,5,4] # # lambda x,y:x*y # def nums(func,array): # li = array.pop(1) # for i in array: # li=func(i,li) # return li # print(nums(lambda x,y:x*y,num)) 4. # num = [2,5,4] # # lambda x,y:x*y # # nums(func,array,init) # # 第一個參數是傳的算法的函數 # #第二個參數是可迭代的對象 # #第三個參數是被+-*/的數。不被寫死,可隨意定義數值 # def nums(func,array,init): # if init is None: #判斷init是否為None # li = array.pop(1) #是None的話,就取數組中的下標為1的數為基數 # else: # li=init #不是None即可定義數值 # for i in array: #遍歷數組, # li=func(i,li) #func(i,li):將函數的x,y寫進來 # return li #得到結果返回值 # print(nums(lambda x,y:x*y,num,2)) 5. #reduce()內置函數的前提,需要引入下面語句 # from functools import reduce # num = [2,5,4] # print(reduce(lambda x,y:x*y,num,2))