Python匿名函式
文章導讀:
以前自己一直沒搞明白Python中的匿名函式,現在拿這個問題基本上搞明白了,拿自己的理解整成一篇文章,附帶大量例子,讓其更加好理解。
在程式語言中,函式的應用:
1. 程式碼塊重複,這時候必須考慮用到函式,降低程式的冗餘度
2. 程式碼塊複雜,這時候可以考慮用到函式,降低程式的可讀性
在Python,有兩種函式,一種是def定義,一種是lambda函式
#假如要求兩個數之和,用普通函式或匿名函式如下:
1. def func(x,y):return x+y
2. lambda x,y: x+y
在程式語言中,C/C++/Java屬於程式式程式設計,而匿名函式(lambda)一般應用於函數語言程式設計中,舉個簡單例子也許比較好理解,對於一個列表,要求大於3的元素.
程式式程式設計實現: 也就是常規的方法
>>> L1 = [1,2,3,4,5]
>>> L2 = []
>>> for i in L1:
if i>3:
L2.append(i)
>>> L2
[4, 5]
函數語言程式設計實現: 運用filter,給其一個判斷條件即可
>>> def func(x): return x>3 #在函式中
>>> filter(func,[1,2,3,4,5])
[4, 5]
如果運用匿名函式,則更加精簡,一行就可以了:
>>> filter(lambda x:x>3,[1,2,3,4,5])
[4, 5]
總結: 從中可以看出,lambda一般應用於函數語言程式設計,程式碼簡潔,常和reduce,filter等函式結合使用。
格式如下:
解構上面的例子
x 為lambda函式的一個引數
: 分割符
x>3 則是返回值,在lambda函式中不能有return,其實:後面就是返回值
為什麼要用匿名函式?
1. 程式一次行使用,所以不需要定義函式名,節省記憶體中變數定義空間
2. 如果想讓程式更加簡潔時。
匿名函式幾個規則:
1. 一般也就一行表示式,必須有返回值
2. 不能有return
3. 可以沒有引數,可以有一個或多個引數
>>> def func(x): x+y
>>> func
<function func at 0x0000000002F48DD8>
>>> lambda x: x+y
<function <lambda> at 0x0000000002F48D68>
無參匿名函式:
------
>>> t = lambda : True #分號前無任何引數
>>> t()
True
等價於下面的def定義的函式
>>> def func(): return True
>>> func()
True
------
>>> s = "this is\na\ttest" #建此字串按照正常情形輸出
>>> s
'this is\na\ttest'
>>> print s.split() #split函式預設分割:空格,換行符,TAB
['this', 'is', 'a', 'test']
>>> ' '.join(s.split()) #用join函式轉一個列表為字串
'this is a test'
等價於
>>> (lambda s:' '.join(s.split()))("this is\na\ttest")
帶引數匿名函式
>>> lambda x: x**3 #一個引數
>>> lambda x,y,z:x+y+z #多個引數
>>> lambda x,y=3: x*y #允許引數存在預設值
匿名函式呼叫
#直接賦值給一個變數,然後再像一般函式呼叫
------
>>> c = lambda x,y,z: x*y*z
>>> c(2,3,4)
24
------
>>> c = lambda x,y=2: x+y #使用了預設值
>>> c(10) #不輸的話,使用預設值2
12
------
>>> a = lambda *z:z #*z返回的是一個元祖
>>> a('Testing1','Testing2')
('Testing1', 'Testing2')
------
>>> c = lambda **Arg: Arg #arg返回的是一個字典
>>> c()
{}
#直接後面傳遞實參
------
>>> (lambda x,y: x if x> y else y)(101,102)
102
------
>>> (lambda x:x**2)(3)
9
#lambda返回的值,結合map,filter,reduce使用
>>> filter(lambda x:x%3==0,[1,2,3,4,5,6])
[3, 6]
等價於下面的列表推導式
>>> l = [x for x in [1,2,3,4,5,6] if x%3==0]
>>> l
[3, 6]
巢狀使用
#lambda巢狀到普通函式中,lambda函式本身做為return的值
------
>>> def increment(n):
... return lambda x: x+n
...
>>> f=increment(4)
>>> f(2)
6
------
>>> def say():
... title = 'Sir,'
... action= lambda x: title + x
... return action
...
>>> act = say()
>>> act('Smith!')
'Sir,Smith!'
大量例子:
例01: 字串聯合,有預設值,也可以x=(lambda...)這種格式
>>> x = (lambda x="Boo",y="Too",z="Zoo": x+y+z)
>>> x("Foo")
'FooTooZoo'
例02: 和列表聯合使用
>>> L = [lambda x:x**2,\
lambda x:x**3,\
lambda x:x**4]
>>> for f in L:
... print f(2)
...
4
8
16
也可以如下面這樣呼叫
>>> print L[0](3)
9
例03: 和字典結合使用
>>> key = 'B'
>>> dic = { 'A': lambda: 2*2,\
... 'B': lambda: 2*4,\
... 'C': lambda: 2*8}
>>> dic[key]()
8
例04: 求最小值
>>> lower = lambda x,y: x if x<y else y
>>> lower('aa','ab')
'aa'
例05: 和map及list聯合使用
>>> import sys
>>> showall = lambda x:list(map(sys.stdout.write,x))
>>> showall(['Jerry\n','Sherry\n','Alice\n'])
Jerry
Sherry
Alice
>>> showall(['Jerry','Sherry','Alice'])
JerrySherryAlice
等價於下面
>>> showall = lambda x: [sys.stdout.write(line) for line in x]
>>> showall(('I\t','Love\t','You!'))
I Love You![None, None, None]
例06: 在Tkinter中定義內聯的callback函式
import sys
from Tkinter import Button,mainloop
x = Button(text='Press me',
command=(lambda:sys.stdout.write('Hello,World\n')))
x.pack()
x.mainloop()
>>>
Hello,World!
Hello,World!
例07: lambda和map聯合使用,
>>> out = lambda *x: sys.stdout.write(' '.join(map(str,x)))
>>> out('This','is','a','book!\n')
This is a book!
例08: 判斷字串是否以某個字母開頭
>>> print (lambda x: x.startswith('B'))('Bob')
True
-----
>>> Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
>>> B_Name= filter(lambda x: x.startswith('B'),Names)
>>> B_Name
['Bob', 'Barbara']
例09: lambda和map聯合使用:
>>> squares = map(lambda x:x**2,range(5))
>>> squares
[0, 1, 4, 9, 16]
例10. lambda和map,filter聯合使用:
>>> squares = map(lambda x:x**2,range(10))
>>> filters = filter(lambda x:x>5 and x<50,squares)
>>> filters
[9, 16, 25, 36, 49]
例11. lambda和sorted聯合使用
#按death名單裡面,按年齡來排序
#匿名函式的值返回給key,進來排序
>>> death = [ ('James',32),
('Alies',20),
('Wendy',25)]
>>> sorted(death,key=lambda age:age[1]) #按照第二個元素,索引為1排序
[('Alies', 20), ('Wendy', 25), ('James', 32)]
例12. lambda和reduce聯合使用
>>> L = [1,2,3,4]
>>> sum = reduce(lambda x,y:x+y,L)
>>> sum
10
例13. 求2-50之間的素數
#素數:只能被1或被自己整除的數
>>> nums = range(2,50)
>>> for i in nums:
nums = filter(lambda x:x==i or x % i,nums)
>>> nums
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
例14. 求兩個列表元素的和
>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> map(lambda x,y:x+y, a,b)
[6, 8, 10, 12]
例15. 求字串每個單詞的長度
>>> sentence = "Welcome To Beijing!"
>>> words = sentence.split()
>>> lengths = map(lambda x:len(x),words)
>>> lengths
[7, 2, 8]
寫成一行:
>>> print map(lambda x:len(x),'Welcome To Beijing!'.split())
例16. 統計Linux系統掛載點
[root@host ~]# mount -v
/dev/mapper/rootVG-root on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/mapper/rootVG-tmp on /tmp type ext3 (rw)
/dev/mapper/rootVG-var on /var type ext3 (rw)
/dev/cciss/c0d0p1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw,size=90%)
>>> import commands
>>> mount = commands.getoutput('mount -v')
>>> lines = mount.splitlines()
>>> point = map(lambda line:line.split()[2],lines)
>>> print point
['/', '/proc', '/sys', '/dev/pts', '/tmp', '/var']
寫成一行:
>>> print map(lambda x:x.split()[2],commands.getoutput('mount -v').splitlines())
效率問題:
#比較def函式和lambda函式效率問題
輸出結果:
1413272496.27
1413272703.05 (Def 函式:207s)
1413272904.49 (Lambda函式:201s)
從上面可以看出,兩者的所需的時間差不多,效率絲毫不受影響.
難點例子:
參考連結:http://segmentfault.com/q/1010000000131575
以前自己一直沒搞明白Python中的匿名函式,現在拿這個問題基本上搞明白了,拿自己的理解整成一篇文章,附帶大量例子,讓其更加好理解。
在程式語言中,函式的應用:
1. 程式碼塊重複,這時候必須考慮用到函式,降低程式的冗餘度
2. 程式碼塊複雜,這時候可以考慮用到函式,降低程式的可讀性
在Python,有兩種函式,一種是def定義,一種是lambda函式
#假如要求兩個數之和,用普通函式或匿名函式如下:
1. def func(x,y):return x+y
2. lambda x,y: x+y
在程式語言中,C/C++/Java屬於程式式程式設計,而匿名函式(lambda)一般應用於函數語言程式設計中,舉個簡單例子也許比較好理解,對於一個列表,要求大於3的元素.
程式式程式設計實現: 也就是常規的方法
>>> L1 = [1,2,3,4,5]
>>> L2 = []
>>> for i in L1:
if i>3:
L2.append(i)
>>> L2
[4, 5]
函數語言程式設計實現: 運用filter,給其一個判斷條件即可
>>> def func(x): return x>3 #在函式中
>>> filter(func,[1,2,3,4,5])
[4, 5]
如果運用匿名函式,則更加精簡,一行就可以了:
>>> filter(lambda x:x>3,[1,2,3,4,5])
[4, 5]
總結: 從中可以看出,lambda一般應用於函數語言程式設計,程式碼簡潔,常和reduce,filter等函式結合使用。
格式如下:
解構上面的例子
x 為lambda函式的一個引數
: 分割符
x>3 則是返回值,在lambda函式中不能有return,其實:後面就是返回值
為什麼要用匿名函式?
1. 程式一次行使用,所以不需要定義函式名,節省記憶體中變數定義空間
2. 如果想讓程式更加簡潔時。
匿名函式幾個規則:
1. 一般也就一行表示式,必須有返回值
2. 不能有return
3. 可以沒有引數,可以有一個或多個引數
>>> def func(x): x+y
>>> func
<function func at 0x0000000002F48DD8>
>>> lambda x: x+y
<function <lambda> at 0x0000000002F48D68>
無參匿名函式:
------
>>> t = lambda : True #分號前無任何引數
>>> t()
True
等價於下面的def定義的函式
>>> def func(): return True
>>> func()
True
------
>>> s = "this is\na\ttest" #建此字串按照正常情形輸出
>>> s
'this is\na\ttest'
>>> print s.split() #split函式預設分割:空格,換行符,TAB
['this', 'is', 'a', 'test']
>>> ' '.join(s.split()) #用join函式轉一個列表為字串
'this is a test'
等價於
>>> (lambda s:' '.join(s.split()))("this is\na\ttest")
帶引數匿名函式
>>> lambda x: x**3 #一個引數
>>> lambda x,y,z:x+y+z #多個引數
>>> lambda x,y=3: x*y #允許引數存在預設值
匿名函式呼叫
#直接賦值給一個變數,然後再像一般函式呼叫
------
>>> c = lambda x,y,z: x*y*z
>>> c(2,3,4)
24
------
>>> c = lambda x,y=2: x+y #使用了預設值
>>> c(10) #不輸的話,使用預設值2
12
------
>>> a = lambda *z:z #*z返回的是一個元祖
>>> a('Testing1','Testing2')
('Testing1', 'Testing2')
------
>>> c = lambda **Arg: Arg #arg返回的是一個字典
>>> c()
{}
#直接後面傳遞實參
------
>>> (lambda x,y: x if x> y else y)(101,102)
102
------
>>> (lambda x:x**2)(3)
9
#lambda返回的值,結合map,filter,reduce使用
>>> filter(lambda x:x%3==0,[1,2,3,4,5,6])
[3, 6]
等價於下面的列表推導式
>>> l = [x for x in [1,2,3,4,5,6] if x%3==0]
>>> l
[3, 6]
巢狀使用
#lambda巢狀到普通函式中,lambda函式本身做為return的值
------
>>> def increment(n):
... return lambda x: x+n
...
>>> f=increment(4)
>>> f(2)
6
------
>>> def say():
... title = 'Sir,'
... action= lambda x: title + x
... return action
...
>>> act = say()
>>> act('Smith!')
'Sir,Smith!'
大量例子:
例01: 字串聯合,有預設值,也可以x=(lambda...)這種格式
>>> x = (lambda x="Boo",y="Too",z="Zoo": x+y+z)
>>> x("Foo")
'FooTooZoo'
例02: 和列表聯合使用
>>> L = [lambda x:x**2,\
lambda x:x**3,\
lambda x:x**4]
>>> for f in L:
... print f(2)
...
4
8
16
也可以如下面這樣呼叫
>>> print L[0](3)
9
例03: 和字典結合使用
>>> key = 'B'
>>> dic = { 'A': lambda: 2*2,\
... 'B': lambda: 2*4,\
... 'C': lambda: 2*8}
>>> dic[key]()
8
例04: 求最小值
>>> lower = lambda x,y: x if x<y else y
>>> lower('aa','ab')
'aa'
例05: 和map及list聯合使用
>>> import sys
>>> showall = lambda x:list(map(sys.stdout.write,x))
>>> showall(['Jerry\n','Sherry\n','Alice\n'])
Jerry
Sherry
Alice
>>> showall(['Jerry','Sherry','Alice'])
JerrySherryAlice
等價於下面
>>> showall = lambda x: [sys.stdout.write(line) for line in x]
>>> showall(('I\t','Love\t','You!'))
I Love You![None, None, None]
例06: 在Tkinter中定義內聯的callback函式
import sys
from Tkinter import Button,mainloop
x = Button(text='Press me',
command=(lambda:sys.stdout.write('Hello,World\n')))
x.pack()
x.mainloop()
>>>
Hello,World!
Hello,World!
例07: lambda和map聯合使用,
>>> out = lambda *x: sys.stdout.write(' '.join(map(str,x)))
>>> out('This','is','a','book!\n')
This is a book!
例08: 判斷字串是否以某個字母開頭
>>> print (lambda x: x.startswith('B'))('Bob')
True
-----
>>> Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach']
>>> B_Name= filter(lambda x: x.startswith('B'),Names)
>>> B_Name
['Bob', 'Barbara']
例09: lambda和map聯合使用:
>>> squares = map(lambda x:x**2,range(5))
>>> squares
[0, 1, 4, 9, 16]
例10. lambda和map,filter聯合使用:
>>> squares = map(lambda x:x**2,range(10))
>>> filters = filter(lambda x:x>5 and x<50,squares)
>>> filters
[9, 16, 25, 36, 49]
例11. lambda和sorted聯合使用
#按death名單裡面,按年齡來排序
#匿名函式的值返回給key,進來排序
>>> death = [ ('James',32),
('Alies',20),
('Wendy',25)]
>>> sorted(death,key=lambda age:age[1]) #按照第二個元素,索引為1排序
[('Alies', 20), ('Wendy', 25), ('James', 32)]
例12. lambda和reduce聯合使用
>>> L = [1,2,3,4]
>>> sum = reduce(lambda x,y:x+y,L)
>>> sum
10
例13. 求2-50之間的素數
#素數:只能被1或被自己整除的數
>>> nums = range(2,50)
>>> for i in nums:
nums = filter(lambda x:x==i or x % i,nums)
>>> nums
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
例14. 求兩個列表元素的和
>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> map(lambda x,y:x+y, a,b)
[6, 8, 10, 12]
例15. 求字串每個單詞的長度
>>> sentence = "Welcome To Beijing!"
>>> words = sentence.split()
>>> lengths = map(lambda x:len(x),words)
>>> lengths
[7, 2, 8]
寫成一行:
>>> print map(lambda x:len(x),'Welcome To Beijing!'.split())
例16. 統計Linux系統掛載點
[root@host ~]# mount -v
/dev/mapper/rootVG-root on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/mapper/rootVG-tmp on /tmp type ext3 (rw)
/dev/mapper/rootVG-var on /var type ext3 (rw)
/dev/cciss/c0d0p1 on /boot type ext3 (rw)
tmpfs on /dev/shm type tmpfs (rw,size=90%)
>>> import commands
>>> mount = commands.getoutput('mount -v')
>>> lines = mount.splitlines()
>>> point = map(lambda line:line.split()[2],lines)
>>> print point
['/', '/proc', '/sys', '/dev/pts', '/tmp', '/var']
寫成一行:
>>> print map(lambda x:x.split()[2],commands.getoutput('mount -v').splitlines())
效率問題:
#比較def函式和lambda函式效率問題
輸出結果:
1413272496.27
1413272703.05 (Def 函式:207s)
1413272904.49 (Lambda函式:201s)
從上面可以看出,兩者的所需的時間差不多,效率絲毫不受影響.
難點例子:
參考連結:http://segmentfault.com/q/1010000000131575
相關文章
- 匿名函式(Python)函式Python
- 1.5.7 Python匿名函式Python函式
- Python函式與lambda 表示式(匿名函式)Python函式
- Python 返回函式+匿名函式Python函式
- python匿名函式的好處Python函式
- Python匿名函式快速入門Python函式
- 初學 Python(十三)——匿名函式Python函式
- Python中的匿名函式-lambdaPython函式
- 深入理解 函式、匿名函式、自執行匿名函式函式
- Python技法3:匿名函式、回撥函式和高階函式Python函式
- PHP匿名函式PHP函式
- Ruby 匿名函式函式
- Golang匿名函式Golang函式
- JavaScript 匿名函式JavaScript函式
- Go 匿名函式Go函式
- JavaScript匿名函式JavaScript函式
- python函式程式設計 返回函式 匿名函式 裝飾器 偏函式Python函式程式設計
- PHP 匿名函式初探PHP函式
- 閉包函式(匿名函式)的理解函式
- 第 8 節:函式-匿名函式、遞迴函式函式遞迴
- Python函數語言程式設計-高階函式、匿名函式、裝飾器、偏函式Python函數程式設計函式
- 兄弟連go教程(14)函式 - 匿名函式Go函式
- PHP 核心特性 - 匿名函式PHP函式
- 裝飾器,匿名函式函式
- js中的匿名函式JS函式
- Js匿名函式小指南JS函式
- JavaScript 匿名函式 閉包JavaScript函式
- 初識Lambda表示式(匿名函式)函式
- 好程式設計師Python教程系列遞迴函式與匿名函式呼叫程式設計師Python遞迴函式
- (011)我們一起學Python;匿名函式,遞迴函式Python函式遞迴
- GO 的匿名函式使用注意Go函式
- 匿名函式有加速的效果??函式
- js 匿名自執行函式JS函式
- 好程式設計師Python培訓分享Python的遞迴函式與匿名函式呼叫程式設計師Python遞迴函式
- python極簡教程05:生成器和匿名函式Python函式
- lambda匿名函式sorted排序函式filter過濾函式map對映函式函式排序Filter
- 從settTimeout到匿名函式、箭頭函式之() => {}函式
- 塊級作用域替代“匿名立即執行函式表示式(匿名IIFE)”函式