摘要:函數接收兩個參數,一個是函數,一個是,將傳入的函數依次作用到序列的每個元素,并把結果作為新的返回。舉例說明,比如我們有一個函數,要把這個函數作用在一個上,就可以用實現如下傳入的第一個參數是,即函數對象本身。
Python內建了map()和reduce()函數。
如果你讀過Google的那篇大名鼎鼎的論文“MapReduce: Simplified Data Processing on Large Clusters”,你就能大概明白map/reduce的概念。
我們先看map。map()函數接收兩個參數,一個是函數,一個是Iterable,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的Iterator返回。
舉例說明,比如我們有一個函數f(x)=x2,要把這個函數作用在一個list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()實現如下:
def f(x): return x*x r = map(f,[1,2,3,4,5,6,7,8,9]) print(list(r)) [1, 4, 9, 16, 25, 36, 49, 64, 81]
map()傳入的第一個參數是f,即函數對象本身。由于結果r是一個Iterator,Iterator是惰性序列,因此通過list()函數讓它把整個序列都計算出來并返回一個list。
你可能會想,不需要map()函數,寫一個循環,也可以計算出結果:
L = [] for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]: L.append(f(n)) print(L)
的確可以,但是,從上面的循環代碼,能一眼看明白“把f(x)作用在list的每一個元素并把結果生成一個新的list”嗎?
所以,map()作為高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意復雜的函數,比如,把這個list所有數字轉為字符串:
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])) ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
只需要一行代碼。
再看reduce的用法。reduce把一個函數作用在一個序列[x1, x2, x3, ...]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
比方說對一個序列求和,就可以用reduce實現:
from functools import reduce def add(x, y): return x + y reduce(add, [1, 3, 5, 7, 9]) 25
當然求和運算可以直接用Python內建函數sum(),沒必要動用reduce。
但是如果要把序列[1, 3, 5, 7, 9]變換成整數13579,reduce就可以派上用場:
from functools import reduce def fn(x, y): return x * 10 + y reduce(fn, [1, 3, 5, 7, 9]) 13579
這個例子本身沒多大用處,但是,如果考慮到字符串str也是一個序列,對上面的例子稍加改動,配合map(),我們就可以寫出把str轉換為int的函數:
from functools import reduce def fn(x, y): return x * 10 + y def char2num(s): digits = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9} return digits[s] reduce(fn, map(char2num, "13579")) 13579
整理成一個str2int的函數就是:
from functools import reduce DIGITS = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9} def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return DIGITS[s] return reduce(fn, map(char2num, s))
還可以用lambda函數進一步簡化成:
from functools import reduce DIGITS = {"0": 0, "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9} def char2num(s): return DIGITS[s] def str2int(s): return reduce(lambda x, y: x * 10 + y, map(char2num, s))
也就是說,假設Python沒有提供int()函數,你完全可以自己寫一個把字符串轉化為整數的函數,而且只需要幾行代碼!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/43051.html
摘要:最近在看英文版,看到了講解等函數,覺得講解的思路特別好。所以,我加上了自己的理解,寫了本篇文章。 最近在看《Think Python》(英文版),看到了講解map, reduce, filter等函數,覺得講解的思路特別好。所以,我加上了自己的理解,寫了本篇文章。 引子 如果要對列表中的數字求和,我們可以這樣做: def add_all(t): t is a list of n...
摘要:用匿名函數有個好處,因為函數沒有名字,不必擔心函數名沖突。和不同的是,把傳入的函數依次作用于每個元素,然后根據返回值是還是決定保留還是丟棄該元素。字符串給出當前平臺使用的行終止符。程序中間的退出,為正常退出。 列表生成式 函數的參數類型 lambda函數 map, reduce, filter, sorted函數 eval, exec, join, zip函數 itertools中的...
摘要:會依次將中的數據傳遞到中,根據返回的或者,留下或者拋棄這個值。而對于字符串,則是根據字符串對應的碼表進行排序。同時也是一個高階函數,可以實現自定義的排序方式。 map/reduce是一種編程思想,在各個領域都有它的實踐。網上有一個簡單的例子解釋map/reduce。比如說你需要數一下某一個圖書館中有多少本藏書。最傻瓜的做法就是排一個人從頭數到尾。這樣速度慢,低效。另一種方法就是先將圖書...
摘要:迭代器可以直接作用于循環的對象統稱為可迭代對象。可以被函數調用并不斷返回下一個值的對象稱為迭代器。這個高階函數,關鍵在于正確實現一個篩選函數。 又是日常嘮嗑的一小段 真的是非常話嘮的在下,日常給自己打點雞血吧。昨晚和老媽聊了一整晚,所以昨天并沒有更新。然后因為很快要開始算個稅減免的部分,對于溫飽線的在下而言,其實減免的可能就只是奶茶錢吧。工作的本質是賺錢,我也很想在30歲之前完成財務自...
摘要:前言繼續向下看廖大教程,看到了函數式編程這一節,當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 前言 繼續向下看廖大教程,看到了函數式編程這一節,當時是覺得沒啥用直接跳過了,這次準備要仔細看一遍了,并記錄下一些心得。 函數式編程 上學期有上一門叫 人工智能 的課,老師強行要我們學了一個叫做 prolog 的語言,哇那感覺確實難受,思維方式完全和之前學過的不一樣,...
閱讀 2074·2019-08-30 15:53
閱讀 3071·2019-08-30 15:44
閱讀 2918·2019-08-30 14:11
閱讀 2916·2019-08-30 14:01
閱讀 2703·2019-08-29 15:16
閱讀 3745·2019-08-29 13:10
閱讀 1246·2019-08-29 10:56
閱讀 2531·2019-08-26 13:58