lambda
lambda 這個關鍵詞在很多語言中都存在。簡單地說,它可以實現函式建立的功能。
如下便是 lambda 的兩種使用方式。
func1 = lambda : <expression()>
func2 = lambda x : <expression(x)>
func3 = lambda x,y : <expression(x,y)>
複製程式碼
在第一條語句中,採用 lambda 建立了一個無參的函式 func1。這和下面採用 def
建立函式的效果是相同的。
def func1():
<expression()>
複製程式碼
在第二條和第三條語句中,分別採用 lambda 建立了需要傳入 1 個引數的函式 func2,以及傳入 2 個引數的函式 func3。這和下面採用def
建立函式的效果是相同的。
def func2(x):
<expression(x)>
def func3(x,y):
<expression(x,y)>
複製程式碼
需要注意的是,呼叫 func1 的時候,雖然不需要傳入引數,但是必須要帶有括號()
,否則返回的只是函式的定義,而非函式執行的結果。
>>> func = lambda : 123
>>> func
<function <lambda> at 0x100f4e1b8>
>>> func()
123
複製程式碼
另外,雖然在上面例子中都將 lambda 建立的函式賦值給了一個函式名,但這並不是必須的。從下面的例子中大家可以看到,很多時候我們都是直接呼叫 lambda 建立的函式,而並沒有命名一個函式,這也是我們常聽說的匿名函式的由來。
map()
map()
函式的常見呼叫形式如下所示:
map(func, iterable)
複製程式碼
map()
需要兩個必填引數,第一個引數是一個函式名,第二個引數是一個可迭代的物件,如列表、元組等。
map()
實現的功能很簡單,就是將第二個引數(iterable)中的每一個元素分別傳給第一個引數(func),依次執行函式得到結果,並將結果組成一個新的list
物件後進行返回。返回結果永遠都是一個list
。
簡單示例如下:
>>> double_func = lambda s : s * 2
>>> map(double_func, [1,2,3,4,5])
[2, 4, 6, 8, 10]
複製程式碼
除了傳入一個可迭代物件這種常見的模式外,map()
還支援傳入多個可迭代物件。
map(func, iterable1, iterable2)
複製程式碼
在傳入多個可迭代物件的情況下,map()
會依次從所有可迭代物件中依次取一個元素,組成一個元組列表,然後將元組依次傳給 func;若可迭代物件的長度不一致,則會以 None 進行補上。
通過以下示例應該就比較容易理解。
>>> plus = lambda x,y : (x or 0) + (y or 0)
>>> map(plus, [1,2,3], [4,5,6])
[5, 7, 9]
>>> map(plus, [1,2,3,4], [4,5,6])
[5, 7, 9, 4]
>>> map(plus, [1,2,3], [4,5,6,7])
[5, 7, 9, 7]
複製程式碼
在上面的例子中,之所以採用x or 0
的形式,是為了防止None + int
出現異常。
需要注意的是,可迭代物件的個數應該與 func 的引數個數一致,否則就會出現異常,因為傳參個數與函式引數個數不一致了,這個應該比較好理解。
>>> plus = lambda x,y : x + y
>>> map(plus, [1,2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes exactly 2 arguments (1 given)
複製程式碼
另外,map()
還存在一種特殊情況,就是 func 為 None。這個時候,map()
仍然是從所有可迭代物件中依次取一個元素,組成一個元組列表,然後將這個元組列表作為結果進行返回。
>>> map(None, [1,2,3,4])
[1, 2, 3, 4]
>>> map(None, [1,2,3,4], [5,6,7,8])
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> map(None, [1,2,3,4], [5,6,7])
[(1, 5), (2, 6), (3, 7), (4, None)]
>>> map(None, [1,2,3,4], [6,7,8,9], [11,12])
[(1, 6, 11), (2, 7, 12), (3, 8, None), (4, 9, None)]
複製程式碼
reduce()
reduce()
函式的呼叫形式如下所示:
reduce(func, iterable[, initializer])
複製程式碼
reduce()
函式的功能是對可迭代物件(iterable)中的元素從左到右進行累計運算,最終得到一個數值。第三個引數 initializer 是初始數值,可以空置,空置為 None 時就從可迭代物件(iterable)的第二個元素開始,並將第一個元素作為之前的結果。
文字描述可能不大清楚,看下reduce()
的原始碼應該就比較清晰了。
def reduce(function, iterable, initializer=None):
it = iter(iterable)
if initializer is None:
try:
initializer = next(it)
except StopIteration:
raise TypeError('reduce() of empty sequence with no initial value')
accum_value = initializer
for x in it:
accum_value = function(accum_value, x)
return accum_value
複製程式碼
再加上如下示例,對reduce()
的功能應該就能掌握了。
>>> plus = lambda x, y : x + y
>>> reduce(plus, [1,2,3,4,5])
15
>>> reduce(plus, [1,2,3,4,5], 10)
25
複製程式碼
filter()
filter()
函式的呼叫形式如下:
filter(func, iterable)
複製程式碼
filter()
有且僅有兩個引數,第一個引數是一個函式名,第二個引數是一個可迭代的物件,如列表、元組等。
filter()
函式的呼叫形式與map()
比較相近,都是將第二個引數(iterable)中的每一個元素分別傳給第一個引數(func),依次執行函式得到結果;差異在於,filter()
會判斷每次執行結果的bool
值,並只將bool
值為true
的篩選出來,組成一個新的列表並進行返回。
>>> mode2 = lambda x : x % 2
>>> filter(mode2, [1,2,3,4,5,6,7,8,9,10])
[1, 3, 5, 7, 9]
複製程式碼
zip()
zip()
函式的呼叫形式如下:
zip([iterable, ...])
複製程式碼
zip()
函式接收一個或多個可迭代物件,將物件中對應的元素打包成一個個元組,然後返回由這些元組組成的列表。
>>> zip([1, 2, 3], ["a", "b", "c"])
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> dict(zip([1, 2, 3], ["a", "b", "c"]))
{1: 'a', 2: 'b', 3: 'c'}
>>> dict(zip([1, 2, 3], ["a", "b"]))
{1: 'a', 2: 'b'}
複製程式碼
打包元組個數與最短列表個數一致。
enumerate()
enumerate()
函式的呼叫形式如下:
enumerate(iterable, [start=0])
複製程式碼
enumerate()
函式用於將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列,同時列出資料和資料下標,一般用在 for 迴圈當中。
>>> enumerate(['Spring', 'Summer', 'Fall', 'Winter'])
<enumerate object at 0x1031780>
>>> list(enumerate(['Spring', 'Summer', 'Fall', 'Winter']))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
複製程式碼
all()、any()
all()
、any()
函式的呼叫形式如下:
all(iterable)
any(iterable)
複製程式碼
這兩個函式比較簡單,即判定一個可迭代物件是否全為 True 或者有為 True 的。
>>> all([0, 1, 2])
False
>>> any([0, 1, 2])
True
複製程式碼
相關文件: