最簡單的理解lambda,map,reduce,filter,列表推導式

Python 2.7
IDE Pycharm 5.0.3


為什么要用Lambda

一句話,因為懶,懶得新建一個一次性使用函數,懶得想函數名,想要更高逼格的pythontic!

比如說,我要實現一個x*y+x的功能,沒有lambda之前我要這樣做:

#定義一個函數
def Whatever(x,y):
    return x*y+x

#調用函數   
f = Whatever(22,3)
print f
#88

而采用lambda之后呢,一行輸出!

print (lambda x,y:x*y+x)(x=22,y=3)

這里解釋一下,我理解的x,y相當于定義的變量名字,而“:”之后的一組運算即是lambda將要返回的一個值,有點像列表推導式哈,還可以這樣使用lambda

f = lambda x,y:x*y+x
print f(22,3)

為什么要用map

繼續上一個例子,用lambda的時候

print (lambda x,y:x*y+x)(x=22,y=3)

這樣寫是不是很難看呢,如果把(x=22,y=3)這個也能寫進一個括號里,那該多好呢,所以就有了map

print map(lambda x,y:x*y+x,[22],[3])
#[88]

其中第一個[22]對應的就是x的取值列表了,而[3]則是y的取值列表,這些都是根據lambda x,y的順序進行的,如果顛倒呢

print map(lambda y,x:x*y+x,[22],[3])
#[69]

所以說,老老實實按照lambda的規則來咯,還有就是map強大就在于,它返回的是一個列表,你可以把它想成一個for循環,它不斷從列表中取值,然后交給lambda,然后得到結果后返回列表存儲,萊格利茲

print map(lambda x,y:x*y+x,[22,3," ","MrLevo"],[3,22,3,2])
#[88, 69, '    ', 'MrLevoMrLevoMrLevo']

很厲害對不對,字符串,空格,都是可以傳遞的對象,比如拿MrLevo來說,相當于x=MrLevo,y=2,所以經過計算,MrLevo*2+MrLevo=MrLevoMrLevoMrLevo字符串的拼接啦就是!

這也就解決了,一個函數傳參數只能傳一組的尷尬,如果你想測試

def Whatever(x,y):
    return x*y+x

這里的x,y為很多組的時候,怎么辦呢,這時候map也就排上用場

print map(Whatever,[22,3," ","MrLevo"],[3,22,3,2])
#[88, 69, '    ', 'MrLevoMrLevoMrLevo']

有幾組來幾組,老紙一塊測了!

注意:賦值要對應,x給了4個,y給3個可不行。
注意:在python 3.0.0.0以后, reduce已經不在built-in function里了, 要用它就得from functools import reduce.
注意:當lambda這個function不存在怎么辦呢,為None怎么辦呢?

print map(None,[22,3," ","MrLevo"],[3,22,3,2])
#[(22, 3), (3, 22), (' ', 3), ('MrLevo', 2)]

其實map就是兩個列表中各取一個數放到function里面計算而已


為什么要用reduce

一句話,就是簡化遞歸,迭代等運算
比如說,你要實現n!你選擇怎么辦呢?

  • 方法一:for循環
def Factorial(n):
    result=1
    for i in range(1,n+1):
        result = result*i
    return result

result = Factorial(5)
print result
#120
  • 方法二,遞歸法
def Factorial(n):
    if n==1 or n==0:
         return 1
    return n*Factorial(n-1)

result = Factorial(5)
print result
#120

上面的還要寫函數,好麻煩呢,怎么辦呢,map說,誰愛上誰上,老紙不干了!reduce笑笑不說話,并且拋出了代碼

print reduce(lambda x,y:x*y,[1,2,3,4,5])
#120

簡單輕松加愉快,這里解釋一下reduce的流程,先取第一第二個數作為x,y然后進行計算,計算出來的數呢,賦給x,然后取第三個數賦給y,再用x,y做計算,再算完的數,又當做下一輪的x,再從列表中取一個數當做y,再來,就是不斷迭代的過程!

  • 步驟一:x=1,y=2
  • 步驟二:x = xy = 12=2
  • 步驟三:x=2 , 取出y=3
  • 步驟四:x=2*3=6
  • 步驟五:x=6 ,取出y=4
  • 步驟六:x = x*y = 24
  • 步驟七:x=24,取出y=5
  • 步驟八:x = 24*5=120
  • 結束

還是不了解的話可以用visualize進行單步模擬

map表示不服,說道要是階乘是250!呢,怎么辦,不會要這么寫到[1,2,3,,,,,,,250]把,于是reduce叫來了列表推導式。。。

print reduce(lambda x,y:x*y,[x for x in range(1,6)])
#120

至于列表推導式是什么,一個例子,還是懶

print [i for i in range(1,6)]
#[1, 2, 3, 4, 5]

它其實相當于這個

result = []
for i in range(1,6):
    result.append(i)
print result
##[1, 2, 3, 4, 5]

Filter表示不服

你們一個個都傳值,有能耐做篩選啊,用能耐來傳布爾啊,來選一組數的奇數,有誰不服?不用多,就[1,2,3,4,5]那小子,就篩你!

列表推導式笑了:拿好不謝

print [x for x in range(1,6) if x%2==1]
#[1, 3, 5]

filter,map,reduce一臉懵逼。。。。。
filter:不行,這個規則太簡單,我們,我們,我們來篩選非空白字符['MrLevo', '', '520', None, ' ']把它篩選成['MrLevo', '520']哼!

列表推導式呵呵:print [x for x in ['MrLevo', '', '520', None, ' '] if x and x.strip()]
filter,map,reduce一臉懵逼。。。。。

filter:我,你,我,額。。。


這里寫圖片描述

列表推導式:算了,這個我不會,你說吧filter。

委屈的filter:

def NoEmpty(x):
    if x and x.strip():
        return x

print filter(NoEmpty,['MrLevo', '', '520', None, ' '])

filter(function, sequence),作用是按照所定義的函數過濾掉列表中的一些元素。刪選規則復雜一點,需要用函數定義那種復雜,可以用filter,不然還是列表推導式把,就是對其他程序員可能不太友好如果列表推導式太長的話。


最后

在leetcode上刷到一道題,easy難度,我的方法擊敗了百分之七的人,哭,,,,,看了擊敗百分之五十的人的答案,只有兩行,哎,要是最強的,估計,一行?復雜度肯定最低。有興趣的可以看看-290. Word Pattern


致謝

@Alex--Python一些特殊用法(map、reduce、filter、lambda、列表推導式等)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容