在學習python函數的過程中,函數的高階應用包括閉包lambda函數,過濾器等都讓我頭痛不已.接下來我把課堂中聽到的筆記進行整理,再寫一遍,希望在提醒自己的同時也能幫助到別人.
首先,我們來看一下什么是閉包,閉包(closure)是函數式編程的重要的語法結構。函數式編程是一種編程范式 (而面向過程編程和面向對象編程也都是編程范式)。在面向過程編程中,我們見到過函數(function);在面向對象編程中,我們見過對象(object)。函數和對象的根本目的是以某種邏輯方式組織代碼,并提高代碼的可重復使用性(reusability)。閉包也是一種組織代碼的結構,它同樣提高了代碼的可重復使用性。
廢話不多說,我們上栗子:
def f1(): def line(x): return 2*x+1 return line myline=f1() print myline(5) 11
在上面f1()的返回結果返回給myline對象,輸出11
如果在line()中引入了外部的變量,情況會怎么樣呢
def f1(): b=10 def line(x): return 2*x+b return line b=5 myline=f1() print myline(5) 20
我們可以看到,line定義的隸屬程序塊中引用了高層級的變量b,但b信息存在于line的定義之外。我們稱b為line的環境變量。事實上,line作為f1的返回值時,line中已經包括b的取值(盡管b并不隸屬于line)。
上面的代碼將打印20,也就是說,line所參照的b值是函數對象定義時可供參考的b值,而不是使用時的b值。
接下來是匿名函數lambda,lambda用途是指定短小的回調函數.lambda將返回一個函數而不是將函數賦值給參數
lambda arg:expression
lambda x,y:x+y f2=lambda x,y:x+y f2(3,4) 7
翻譯成普通函數就是
def f2(x,y) return x+y a=f2() a(3,4)
lambda也支持使用默認參數
f=lambda x,y,z=10 :x+y+z f(4,5) 19
l3=[(lambda x:x*2),(lambda y :y*3)] for i in l3: print i(4) 8 12
接下來是3個python內置函數 filter(),map(),reduce()
filter()用來過濾,filter的語法是
filter(func,seq)
函數接收一個函數和一個序列,把函數一次用于序列的每個元素,如果為True則保留
l1=[1,2,3,4,42,60] def f1(x): if x>20: return True else: return False filter(f1,l1) [42, 60]
map()和filter()一樣,也接收了一個函數和一個序列,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的list返回
l1=[1,2,3,4,42,60] map(lambda x:x*2,l1) [2, 4, 6, 8, 84, 120]
map中可以跟多個list,
def abc(x,y): return x*100+y list1=[11,22,33] list2=[44,55,66] map(abc,list1,list2) [1144, 2255, 3366]
reduce()迭代器
reduce(func,seq[,init])
對sequence中的item順序迭代調用function,如果有init,還可以作為初始值調用,例如可以用來對List求和:
def add(x,y): return x+y reduce(add,range(1,11),10) 65
完成從1加到11,最后加上初始值10,最后是65
接下來完成以下馬哥在視頻中的幾個練習
返回/etc/passwd中包含了/bin/bash字串的所有用戶名
f1=open('/etc/passwd') b=filter(lambda i:'/etc/passwd' in i,f1.readlines()) re.search('(\w*):',str(b)).groups(0)
將/etc/passwd中的每一行都分隔為一個列表
f1=open('/etc/passwd') f1.readline()
用折疊的方式求階乘
l1=[1,2,3,4] reduce(lambda x,y:x*y,l1)
原創文章,作者:海馬,如若轉載,請注明出處:http://www.www58058.com/10094
非常不錯。贊