日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python函数式编程-map()、zip()、filter()、reduce()、lambda()

發布時間:2023/12/13 python 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python函数式编程-map()、zip()、filter()、reduce()、lambda() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

三個函數比較類似,都是應用于序列的內置函數。常見的序列包括list、tuple、str


map函數


map函數會根據提供的函數對指定序列做映射。

map函數的定義:

map(function, sequence[, sequence, ...]) -> list

map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,并把結果作為新的list返回。


1、當seq只有一個時,將函數func作用于這個seq的每個元素上,并得到一個新的seq。
讓我們來看一下只有一個seq的時候,map()函數是如何工作的。

示例一

比如要對一個序列中的每個元素進行平方運算:

map(lambda x: x ** 2, [1, 2, 3, 4, 5])

返回結果為:

[1, 4, 9, 16, 25]

或者

>>> def f(x): ... return x * x ... >>> map(f, [1, 2, 3, 4, 5]) [1, 4, 9, 16, 25]

map()傳入的第一個參數是f,即函數對象本身。

注意:map()函數不改變原有的 list,而是返回一個新的 list。

不需要map()函數,寫一個循環,也可以計算出結果

L = [] for n in [1, 2, 3, 4, 5]:L.append(f(n)) print L

把f(x)作用在list的每一個元素并把結果生成一個新的list。

示例二

#使用lambda >>> print map(lambda x: x % 2, range(7)) [0, 1, 0, 1, 0, 1, 0] #使用列表解析 >>> print [x % 2 for x in range(7)] [0, 1, 0, 1, 0, 1, 0]

2、當seq多于一個時,map可以并行(注意是并行)地對每個seq執行如下圖所示的過程

在參數存在多個序列時,會依次以每個序列中相同位置的元素做參數調用function函數。

示例

比如要對兩個序列中的元素依次求和。

map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])

map返回的list中第一個元素為,參數序列1的第一個元素加參數序列2中的第一個元素(1 + 2),
list中的第二個元素為,參數序列1中的第二個元素加參數序列2中的第二個元素(3 + 4),
依次類推,最后的返回結果為:

[3, 7, 11, 15, 19]

要注意function函數的參數數量,要和map中提供的集合數量相匹配。
如果集合長度不相等,會以最小長度對所有集合進行截取。


當函數為None時,操作和zip相似

map(None, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])

返回結果為:

[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]

map()作為高階函數,事實上它把運算規則抽象了,因此,我們不但可以計算簡單的f(x)=x2,還可以計算任意復雜的函數,比如,把這個list所有數字轉為字符串

>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]) ['1', '2', '3', '4', '5', '6', '7', '8', '9']

由于list包含的元素可以是任何類型,因此,map() 不僅僅可以處理只包含數值的 list,事實上它可以處理包含任意類型的 list,只要傳入的函數f可以處理這種數據類型。

比如假設用戶輸入的英文名字不規范,沒有按照首字母大寫,后續字母小寫的規則,請利用map()函數,把一個list(包含若干不規范的英文名字)變成一個包含規范英文名字的list:
輸入:[‘adam’, ‘LISA’, ‘barT’]
輸出:[‘Adam’, ‘Lisa’, ‘Bart’]

def format_name(s):s1=s[0:1].upper()+s[1:].lower();return s1;print map(format_name, ['adam', 'LISA', 'barT']) ***將元組轉換成list*** >>> map(int, (1,2,3)) [1, 2, 3] ***將字符串轉換成list*** >>> map(int, '1234') [1, 2, 3, 4] ***提取字典的key,并將結果存放在一個list中*** >>> map(int, {1:2,2:3,3:4}) [1, 2, 3] ***字符串轉換成元組,并將結果以列表的形式返回*** >>> map(tuple, 'agdf') [('a',), ('g',), ('d',), ('f',)] #將小寫轉成大寫 def u_to_l (s):return s.upper() print map(u_to_l,'asdfd')

zip函數


Python函數式編程之zip()
zip()函數具體的工作機制是,將每個列表中同一位置的元素取出來組成一個元組,存放到一個列表中,然后返回這個列表。

>>> x = [1,2,3] >>> y = ['a','b','c'] >>> z = [4,5,6] >>> zip_xyz = zip(x, y, z) >>> print zip_xyz [(1, 'a', 4), (2, 'b', 5), (3, 'c', 6)]

對于長度不同的seq,zip()函數又怎么處理呢?

>>> a = [1,2,3] >>> b = [4,5,6,7] >>> zip_ab = zip(a, b) >>> print zip_ab [(1, 4), (2, 5), (3, 6)]

從上面的例子可以看出,當seq的長度不一致時,zip()會以最短的那個seq為主,進行處理,然后將多余的舍棄掉。

zip()對只有一個seq的處理:

>>> c = ['a', 'b', 'c'] >>> zip_c = zip(c) >>> print zip_c [('a',), ('b',), ('c',)]

unzip

>>> a = [1, 2, 3] >>> b = ['a', 'b', 'c'] >>> zip_ab = zip(a,b) >>> un_zip = zip(*zip_ab) >>> print un_zip [(1, 2, 3), ('a', 'b', 'c')]

一般認為這是一個unzip過程,工作原理如下:
在運行zip(*zip_ab)之前,zip_ab的值是:[(1, ‘a’), (2, ‘b’), (3, ‘c’)]
而zip(*zip_ab)就等價于zip((1, ‘a’), (2, ‘b’), (3, ‘c’))
所以得出結果:[(1, 2, 3), (‘a’, ‘b’, ‘c’)]

>>> x = [1,'a','b'] >>> zip_rx = zip(* [x] * 3) >>> print zip_rx [(1, 1, 1), ('a', 'a', 'a'), ('b', 'b', 'b')]

首先 [x]生成一個列表的列表:[[1, ‘a’, ‘b’]],這個列表中只有一個元素[1,’a’,’b’]
其次[x] * 3,表示將列表中的元素打印三次,即生成了含有三個元素的列表:
[[1, ‘a’, ‘b’], [1, ‘a’, ‘b’], [1, ‘a’, ‘b’]]
最后是zip(* [x] * 3)就等價于
zip([1, ‘a’, ‘b’], [1, ‘a’, ‘b’], [1, ‘a’, ‘b’])


filter函數


filter函數會對指定序列執行過濾操作。
filter函數的定義:

filter(function or None, sequence) -> list, tuple, or string

filter函數會對序列參數sequence中的每個元素調用function函數,最后返回的結果包含調用結果為True的元素序列。返回值的類型和參數sequence的類型相同. func函數是一個布爾函數,filter()函數調用這個函數一次作用于seq中的每一個元素,篩選出符合條件的元素,并以列表的形式返回。

示例一

比如返回序列中的所有偶數:

def is_even(x): return x & 1 != 0filter(is_even, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

返回結果為:
[1, 3, 5, 7, 9]
如果function參數為None,返回結果和sequence參數相同。

示例二

假如有個列表,列表中有幾個數字,現在我想從這些數字中,選出即能被2整除又能被3整除的數。

nums = [2,3,6,12,15,18] def nums_res (x):return x % 2 == 0 and x % 3 == 0 print filter(nums_res, nums) 執行結果:[6, 12, 18]

如果使用普通方法的話,就需要使用for循環去挨個挨個遍歷list中的元素。當然我們也可以使用列表解析法:

>>> print [x for x in nums if x % 2 == 0 and x % 3 == 0] [6, 12, 18]

reduce函數


reduce函數,即為化簡函數,reduce函數會對參數序列中元素進行累積。
reduce函數的定義:

reduce(function, sequence[, initial]) -> value

function參數是一個有兩個參數的函數,reduce依次從sequence中取一個元素,和上一次調用function的結果做參數再次調用function。
第一次調用function時,如果提供initial參數,會以sequence中的第一個元素和initial作為參數調用function,否則會以序列sequence中的前兩個元素做參數調用function。

reduce()函數的執行過程如下圖所示

reduce把一個函數作用在一個序列[x1, x2, x3…]上,這個函數必須接收兩個參數,reduce把結果繼續和序列的下一個元素做累積計算,其效果就是:

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

示例一

比方說對一個序列求和,就可以用reduce實現

>>> def add(x, y): ... return x + y ... >>> reduce(add, [1, 3, 5, 7, 9]) 25

或者

reduce(lambda x, y: x + y, [1, 3, 5, 7, 9])

結果為25

或者

reduce(lambda x, y: x + y, [3, 5, 7, 9], 1)

結果為25( ((((1+3)+5)+7)+9) )

當然求和運算可以直接用Python內建函數sum(),沒必要動用reduce。

示例二

從reduce函數的執行過程,很容易聯想到求一個數的階乘,而python中并沒有給出一個求階乘的內置函數,正好就拿這個例子來說明reduce函數。

#未指定init的情況 >>> n = 6 >>> print reduce(lambda x, y: x * y, range(1, n)) 120

上面的例子中range(1,6)函數生成的是一個[1, 2, 3, 4, 5]這樣的列表,這里我們給它個名叫seq1吧,reduce()函數執行時,由于沒有指定init參數,所以將取seq1中的第一個元素1,作為第一個元素,由于前面的lambda有2個變量,所以需要兩個實參,于是就取seq1中的第2個元素2,與第一個元素1一起傳入lambda中去執行,并將返回結果2,并同下一個元素3再一起傳入lambda中執行,再次返回的結果,作為下一次執行的第一個元素,依次類推,就得出結果5! = 120。

如果我們希望得到階乘的結果再多增加幾倍,可以啟用init這個可選項。如:

>>> print reduce(lambda x, y: x * y, range(1, n),2) 240

這個時候,就會將init作為第一個元素,和seq1中的第一個元素1一起傳入lambda函數中去執行,返回結果再作為下一次的第一個元素。


但是如果要把序列[1, 3, 5, 7, 9]變換成整數13579,reduce就可以派上用場

>>> def fn(x, y): ... return x * 10 + y ... >>> reduce(fn, [1, 3, 5, 7, 9]) 13579

這個例子本身沒多大用處,但是,如果考慮到字符串str也是一個序列,對上面的例子稍加改動,配合map(),我們就可以寫出把str轉換為int的函數:

>>> def fn(x, y): ... return x * 10 + y ... >>> def char2num(s): ... return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] ... >>> reduce(fn, map(char2num, '13579')) 13579

整理成一個str2int的函數就是:

def str2int(s):def fn(x, y):return x * 10 + ydef char2num(s):return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]return reduce(fn, map(char2num, s))

還可以用lambda函數進一步簡化成

def char2num(s):return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s] def str2int(s):return reduce(lambda x,y: x*10+y, map(char2num, s))

也就是說,假設Python沒有提供int()函數,你完全可以自己寫一個把字符串轉化為整數的函數,而且只需要幾行代碼

注意function函數不能為None。


lambda函數


Python中,lambda函數也叫匿名函數,及即沒有具體名稱的函數,它允許快速定義單行函數,類似于C語言的宏,可以用在任何需要函數的地方。這區別于def定義的函數。
lambda與def的區別:

1)def創建的方法是有名稱的,而lambda沒有。
2)lambda會返回一個函數對象,但這個對象不會賦給一個標識符,而def則會把函數對象賦值給一個變量(函數名)。
3)lambda只是一個表達式,而def則是一個語句。
4)lambda表達式” : “后面,只能有一個表達式,def則可以有多個。
5)像if或for或print等語句不能用于lambda中,def可以。
6)lambda一般用來定義簡單的函數,而def可以定義復雜的函數。
6)lambda函數不能共享給別的程序調用,def可以。

lambda語法格式:
lambda 變量 : 要執行的語句

lambda [arg1 [, agr2,…..argn]] : expression

1、單個參數的: >>> g = lambda x : x ** 2 >>> print g(3) 9 2、多個參數的: >>> g = lambda x, y, z : (x + y) ** z >>> print g(1,2,2) 9

lambda表達式會返回一個函數對象,如果沒有變量接受這個返回值的話,它很快就會被丟棄。也正是由于lambda只是一個表達式,所以它可以直接作為list和dict的成員。如:

>>> list_a = [lambda a: a**3, lambda b: b**3] >>> list_a[0] <function <lambda> at 0x0259B8B0> >>> g = list_a[0] >>> g(2) 8

lambda表達式中,冒號前面是參數,可以有多個,用逗號分隔,冒號右邊是返回值。


參考文獻


python中的map、filter、reduce函數

python map函數

Python map()函數的用法

Python reduce()函數的用法

Python filter()函數的用法

Python lambda函數的用法

總結

以上是生活随笔為你收集整理的Python函数式编程-map()、zip()、filter()、reduce()、lambda()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。