Python特殊語法:filter、map、reduce、lambda、yield

內容源自互聯網  轉自http://blog.csdn.net/wanghai__/article/details/6936633


Python內置了一些非常有趣但非常有用的函數,充分體現了Python的語言魅力!

filter(function, sequence):對sequence中的item依次執行function(item),將執行結果爲True的item組成一個List/String/Tuple(取決於sequence的類型)返回:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

>>> def f(x): return x != 'a'
>>> filter(f, "abcdef")
'bcdef'

map(function, sequence) :對sequence中的item依次執行function(item),見執行結果組成一個List返回:

>>> def cube(x): return x*x*x
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

>>> def cube(x) : return x + x
...
>>> map(cube , "abcde")
['aa', 'bb', 'cc', 'dd', 'ee']

另外map也支持多個sequence,這就要求function也支持相應數量的參數輸入:

>>> def add(x, y): return x+y
>>> map(add, range(8), range(8))
[0, 2, 4, 6, 8, 10, 12, 14]

reduce(function, sequence, starting_value):對sequence中的item順序迭代調用function,如果有starting_value,還可以作爲初始值調用,例如可以用來對List求和:

>>> def add(x,y): return x + y
>>> reduce(add, range(1, 11))
55 (注:1+2+3+4+5+6+7+8+9+10)

>>> reduce(add, range(1, 11), 20)
75 (注:1+2+3+4+5+6+7+8+9+10+20)

lambda:這是Python支持一種有趣的語法,它允許你快速定義單行的最小函數,類似與C語言中的宏,這些叫做lambda的函數,是從LISP借用來的,可以用在任何需要函數的地方:
>>> g = lambda x: x * 2 
>>> g(3)
6
>>> (lambda x: x * 2)(3) 
6


######yield#####

generator歸根到底是一個函數的返回值,這個函數是包含“yield”關鍵字的python函數。

是不是可以這麼說(不是很確定,似乎可以這麼理解)
1,凡包含“yield”關鍵字的函數,都返回generator
2,generator不是函數,而是函數執行後構造的對象,是一種iterator。
3,generator可以像iterator一樣的用。

generator的根源是PEP 255,其中列出了generator在Python存在的原因,簡單的講,Generator在需要時返回中間值,能夠保存當前的狀態,等待下一次的返回要求。

xrange/range的區別或許可以幫我們理解這一點,xrange之所以存在,是因爲range需要一次完成列表的初始化,存儲等等,從C的角度來理解,就是,用range等於先malloc足夠的內存,然後完成值的準備,等待調用(遍歷等等)。而xrange則不這麼幹,什麼時候要的時候,什麼時候給值。所以,在Python 2.x中,type(range(10))是一個List,是內存中的靜態數據;而type(xrange(10))則是一個range type。

到Python 3.x,xrange徹底替代了range函數。

這樣設計的目的無非就是節省內存 ,千八百數字的無所謂,但ython 2.x的long int和Python 3.x的Int是無限制(用官方語言來說就是可以佔滿內存)。

generator爲了滿足這種需求設計的,狀態得到了保存,隨取隨算。

PEP 255有一句: a Python generator is a kind of Python iterator[1], but of an especially powerful kind.

Python的產生器就是一種迭代器...
因爲它是一種迭代器,所以,他可以用到for等控制流中。

def gen():
print "one"
yield 1
print "two"
yield 2
print "three"
yield 3

type(gen)
type(gen())

可以看到gen是函數,而gen()是generator,應該說,函數gen執行的返回值是生成一個generator。

generator的方法之一就是next()。
a=gen()
a.next()
a.next()
a.next()
a.next()
三次next,分別返回了1,2,3,最後一次,已到達末尾,發生StopIteration錯誤。


而yield的作用就是,每次發生next()調用,函數執行完yield語句之後在掛起,這時返回yield的值(你原因yield啥就yield啥),整個函數狀態被保存,等待下一次next()調用;
下次next()調用發生時,從yield後的語句開始執行(有yiled也在循環體內,未必一定是順序的),直到再次遇到yield爲止,然後重複刪除動作。

yield 可以解讀爲"返回然後等待"。知道所有yield語句完成,這時如果再次調用next(),則發生StopIteration異常,當然,在for循環之類的語句中會被自動處理。

<--- XDICT英漢辭典 --->
yield
[jiːld]
n. 生產量,投資收益
vt. 生產,給予,同意,被迫放棄,放縱
vi. 出產,屈服,投降


在這裏,當然是“生產”的意思。

PEP 255詳細解釋了爲什麼是"新關鍵字" yield,而不是return 變體等等的原因。

我想,一個簡單的原因可能是return已經被大家清楚、牢靠的理解成了"函數的結束並返回“,而不是”返回並掛起“。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章