Python開發之幾個內聯函數的介紹

Python本身有很多內置的函數供開發人員使用,其中有幾個感覺挺有學習價值,在這裏記錄一下。

  • lambda
  • zip
  • filter
  • map
  • reduce

lambda

Python允許單行快速定義一個最小函數,這便是lambda函數。比如,原本使用常規的函數去定義,它可能是如下形式:

def add(x,y):
    return x+y

而使用lambda函數的語法形式,它可以輕鬆簡化爲單行代碼:

add_by_lambda = lambda x,y: x+y

其中,x,y便是函數入口參數,而後面則是具體的函數體,默認lambda可以返回一個函數對象,相應的調用效果類似:

print add(1, 1)
print add_by_lambda(1, 1)

甚至還可以直接在後面追加實參來直接獲取返回值,比如lambda x,y : x+y, 1, 1返回結果就是2

lambda函數使得Python代碼可以變得更加優雅、簡潔。

zip

Python內置的zip函數接受任意多個list作爲參數,並把相同索引的元素組合成tuple,最後形成一個新的list,新的list長度以傳入參數的最小值爲準。比如:

x = [ 1, 2, 3]  
y = [ 'a', 'b', 'aa', 'bb']  
z = [ 'A', 'B', 'C']

# zip them!
print zip(x,y,z)

# (*) 是 zip的反函數
print zip(*zip(x,y,z))  
print zip(*([(1, 'a', 'aa'), (2, 'b', 'bb'), (3, 'c', 'cc')]))  

filter

filter函數接受兩個參數,func和list,而經過過濾後返回一個list,其中func函數對象只能有一個傳入參數。原理便是根據列表list中所有元素作爲參數傳遞給函數func,返回可以令func返回真的元素的列表,如果func爲None,那麼會使用默認的Python內置的identity函數直接判斷元素的True or False。

例如:

a = [1,2,3,4,5,6,7]  
b=filter(lambda x:x>2, a)  
print b

#過濾奇數集
a = [1,2,3,4,5,6,7]  
b=filter(lambda x:x%2, a)  
print b  

map

map函數是一個很強大的一個映射函數,其傳入兩個參數,一個是func,一個是list,而功效便是func作用於給定序列的每個元素,並用一個列表來提供返回值。例如:

a=[0,1,2,3,4,5,6,7]  
map(lambda x:x+3, a)

a=[1,2,3]  
b=[4,5,6]  
map(lambda x,y:x+y, a,b)  
#my_map函數實現
def my_map(func, *args):  
       return [ func(arg) for arg in args ]

上面的代碼假使通過for循環方式實現的話,不僅代碼行數變多,而且可能多層if判斷,結構冗餘,完全沒有map方式來得簡潔、優雅。

reduce

reduce函數傳入參數爲func和list,其遍歷list元素,並調用func函數實現累積,具體效果便是:

reduce(f, [x1, x2, x3, x4]) = f ( f ( f ( x1, x2 ), x3 ), x4 )

使用範例如下:

#str to int
def str2int(s):  
       return reduce(lambda x,y: x*10+y, map(int, s))

一些妙用

以上簡單介紹了五個強大簡潔的Python內置函數的用法,下面附上一些小巧精妙的例子,以饗讀者。

#兩個list,取(x - y) + (y - x)
x=[{'a': 1, 'b': 2}, {'c': 3}, {'d': 4}]  
y=[{'a': 1}, {'c': 3}, {'e': 5}]

filter(lambda z: (x+y).count(z)<2, (x+y))  
#flatten out nested sublist
#result: [ 1, 2, 3, 4, 5 ]
import operator  
reduce( operator.concat, [ [ 1, 2 ], [ 3, 4 ], [ ], [ 5 ] ], [ ] )  
#多項式求和
import operator  
def evaluate (a, x):  
       xi = map( lambda i: x**i, range( 0, len(a)))
       axi = map(operator.mul, a, xi)
       return reduce( operator.add, axi, 0 )
#數據庫SQL
reduce( max, map( Camera.pixels, filter(  
        lambda c: c.brand() == "Nikon", cameras ) ) )

#maybe equals
SELECT max(pixels)  
FROM cameras  
WHERE brand = “Nikon”

#There.
#cameras is a sequence
#where clause is a filter
#pixels is a map
#max is a reduce
#一行併發
import urllib2  
from multiprocessing.dummy import Pool as ThreadPool

urls = [  
           'http://www.python.org',
           'http://www.google.com',
           'http://www.baidu.com',
           'http://www.python.org/community/',
           'http://www.saltstack.com'
           ]

#pool = ThreadPool()
pool = ThreadPool(4) # Sets the pool size to 4

result = pool.map(urllib2.urlopen, urls)  
pool.close()  
pool.join()  

上述的代碼實現相較普通的for循環等實現方式是不是特別的簡潔、優雅呢? 嘗試着使用它們吧!

發佈了2 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章