Map,Filter 和 Reduce
Map,Filter 和 Reduce 三個(gè)函數(shù)能為函數(shù)式編程提供便利。我們會(huì)通過實(shí)例一個(gè)一個(gè)討論并理解它們。
Map
Map會(huì)將一個(gè)函數(shù)映射到一個(gè)輸出列表的所有元素上。這是它的規(guī)范:
map(function_to_apply, list_of_inputs)
大多數(shù)時(shí)候,我們要把列表中所有元素一個(gè)個(gè)地傳遞給一個(gè)函數(shù),并收集輸出。比方說:
items = [1, 2, 3, 4, 5]
squared = []
for i in items:
??? squared.append(i**2)
Map可以讓我們用一種簡(jiǎn)單而漂亮得多的方式來實(shí)現(xiàn)。就是這樣:
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items))
大多數(shù)時(shí)候,我們使用匿名函數(shù)(lambdas)來配合map, 所以我在上面也是這么做的。 不僅用于一列表的輸入。 我們甚至可以用于一列表的函數(shù)!
def multiply(x):
??? return (x*x)
def add(x):
??? return (x+x)
funcs = [multiply, add]
for i in range(5):
??? value = map(lambda x: x(i), funcs)
??? print(list(value))
??? # 譯者注:上面print時(shí),加了list轉(zhuǎn)換,是為了python2/3的兼容性
??? # 在python2中map直接返回列表,但在python3中返回迭代器
??? # 因此為了兼容python3, 需要list轉(zhuǎn)換一下
Filter
顧名思義,filter過濾列表中的元素,并且返回一個(gè)由所有符合要求的元素所構(gòu)成的列表,符合要求即函數(shù)映射到該元素時(shí)返回值為True. 這里是一個(gè)簡(jiǎn)短的例子:
number_list = range(-5, 5)
less_than_zero = filter(lambda x: x < 0, number_list)
print(list(less_than_zero))
# 譯者注:上面print時(shí),加了list轉(zhuǎn)換,是為了python2/3的兼容性
# 在python2中filter直接返回列表,但在python3中返回迭代器
# 因此為了兼容python3, 需要list轉(zhuǎn)換一下
# Output: [-5, -4, -3, -2, -1]
這個(gè)filter類似于一個(gè)for循環(huán),但它是一個(gè)內(nèi)置函數(shù),并且更快。
注意:如果map和filter對(duì)你來說看起來并不優(yōu)雅的話,那么你可以看看另外一章:列表/字典/元組推導(dǎo)式。
譯者注:大部分情況下推導(dǎo)式的可讀性更好
Reduce
當(dāng)需要對(duì)一個(gè)列表進(jìn)行一些計(jì)算并返回結(jié)果時(shí),Reduce 是個(gè)非常有用的函數(shù)。舉個(gè)例子,當(dāng)你需要計(jì)算一個(gè)整數(shù)列表的乘積時(shí)。
通常在 python 中你可能會(huì)使用基本的 for 循環(huán)來完成這個(gè)任務(wù)。
現(xiàn)在我們來試試 reduce:
from functools import reduce
product = reduce( (lambda x, y: x * y), [1, 2, 3, 4] )
set(集合)數(shù)據(jù)結(jié)構(gòu)
set(集合)是一個(gè)非常有用的數(shù)據(jù)結(jié)構(gòu)。它與列表(list)的行為類似,區(qū)別在于set不能包含重復(fù)的值。
這在很多情況下非常有用。例如你可能想檢查列表中是否包含重復(fù)的元素,你有兩個(gè)選擇,第一個(gè)需要使用for循環(huán),就像這樣:
some_list = ['a', 'b', 'c', 'b', 'd', 'm', 'n', 'n']
duplicates = []
for value in some_list:
??? if some_list.count(value) > 1:
??????? if value not in duplicates:
??????????? duplicates.append(value)
print(duplicates)
### 輸出: ['b', 'n']
但還有一種更簡(jiǎn)單更優(yōu)雅的解決方案,那就是使用集合(sets),你直接這樣做:
some_list = ['a', 'b', 'c', 'b', 'd', 'm', 'n', 'n']
duplicates = set([x for x in some_list if some_list.count(x) > 1])
print(duplicates)
### 輸出: set(['b', 'n'])
集合還有一些其它方法,下面我們介紹其中一部分。
交集
你可以對(duì)?兩個(gè)集合的交集(兩個(gè)集合中都有的數(shù)據(jù)),如下:
valid = set(['yellow', 'red', 'blue', 'green', 'black'])
input_set = set(['red', 'brown'])
print(input_set.intersection(valid))
### 輸出: set(['red'])
差集
你可以用差集(difference)找出有效的數(shù)據(jù),相當(dāng)于用一個(gè)集合減去另一個(gè)集合的數(shù)據(jù),例
如:
valid = set(['yellow', 'red', 'blue', 'green', 'black'])
input_set = set(['red', 'brown'])
print(input_set.difference(valid))
### 輸出: set(['brown'])
你也可以用符號(hào)來創(chuàng)建集合,如:
a_set = {'red', 'blue', 'green'}
print(type(a_set))
### 輸出: <type 'set'>
集合還有一些其它方法,我會(huì)建議訪問官方文檔并做個(gè)快速閱讀。