Python 函數語言程式設計,沒什麼廢話,直接看用法和程式碼

yongxinz發表於2018-10-26

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
複製程式碼



相關文件:

zhuanlan.zhihu.com/p/23384430

coolshell.cn/articles/10…

debugtalk.com/post/python…

相關文章