1. 程式人生 > >python高階函數,map,filter,reduce,ord,以及lambda表達式

python高階函數,map,filter,reduce,ord,以及lambda表達式

技術 進制 har err 就是 很多 只需要 作用 img

為什麽我突然扯出這麽幾個函數,是因為我今天在看流暢的python這本書的時候,裏面有一部分內容看的有點懵逼。

>>> symbols = $¢£¥€¤
>>> beyond_ascii = [ord(s) for s in symbols if ord(s) > 127]
>>> beyond_ascii
[162, 163, 165, 8364, 164]
>>> beyond_ascii = list(filter(lambda c: c > 127, map(ord, symbols)))
>>> beyond_ascii [162, 163, 165, 8364, 164]

下面根據這裏面的所有的函數展開整理一下

1.ord是將字符轉換為10進制的數

2.而map是將列表內元素當做某個函數的參數得到的結果組成的新列表

3.filter是將一個列表按照一定的規則過濾生成的列表

1.lambda表達式

ambda表達式,通常是在需要一個函數,但是又不想費神去命名一個函數的場合下使用,也就是指匿名函數

示例:

add = lambda x, y : x+y
add(1,2)  # 結果為3

1.1應用在函數式編程中

Python提供了很多函數式編程的特性,如:map、reduce、filter、sorted等這些函數都支持函數作為參數,lambda函數就可以應用在函數式編程中。如下:

# 需求:將列表中的元素按照絕對值大小進行升序排列
list1 = [3,5,-4,-1,0,-2,-6]
sorted(list1, key=lambda x: abs(x))

當然,也可以如下:

list1 = [3,5,-4,-1,0,-2,-6]
def get_abs(x):
    return abs(x)
sorted(list1,key=get_abs)

只不過這種方式的代碼看起來不夠Pythonic

1.2應用在閉包中

def get_y(a,b):
     return lambda x:ax+b
y1 = get_y(1,1)
y1(
1) # 結果為2

當然,也可以用常規函數實現閉包,如下:

def get_y(a,b):
    def func(x):
        return ax+b
    return func
y1 = get_y(1,1)
y1(1) # 結果為2

只不過這種方式顯得有點啰嗦。

那麽是不是任何情況下lambda函數都要比常規函數更清晰明了呢?

肯定不是。

Python之禪中有這麽一句話:Explicit is better than implicit(明了勝於晦澀),就是說那種方式更清晰就用哪一種方式,不要盲目的都使用lambda表達式。

2.Map函數

map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次作用到序列的每個元素,並把結果作為新的list返回。
舉例說明
比如我們有一個函數f(x)=x2,要把這個函數作用在一個list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()實現如下:
技術分享圖片

現在,我們用Python代碼實現:

>>> def f(x):
...     return x * x
...
>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()傳入的第一個參數是f,即函數對象本身。
你可能會想,不需要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所有數字轉為字符串:

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

只需要一行代碼。

3.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

當然求和運算可以直接用Python內建函數sum(),沒必要動用reduce。
但是如果要把序列[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 + 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]

    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()函數,你完全可以自己寫一個把字符串轉化為整數的函數,而且只需要幾行代碼!

4.Filter函數

Python內建的filter()函數用於過濾序列。

和map()類似,filter()也接收一個函數和一個序列。和map()不同的時,filter()把傳入的函數依次作用於每個元素,然後根據返回值是True還是False決定保留還是丟棄該元素。

True保留,False丟棄
例如,在一個list中,刪掉偶數,只保留奇數,可以這麽寫:

def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])

# 結果: [1, 5, 9, 15]

把一個序列中的空字符串刪掉,可以這麽寫:

def not_empty(s):
    return s and s.strip()

filter(not_empty, [A, ‘‘, B, None, C,   ])

# 結果: [‘A‘, ‘B‘, ‘C‘]

可見用filter()這個高階函數,關鍵在於正確實現一個“篩選”函數。

5.ord函數

ord() 函數是 chr() 函數(對於8位的ASCII字符串)或 unichr() 函數(對於Unicode對象)的配對函數,它以一個字符(長度為1的字符串)作為參數,返回對應的 ASCII 數值,或者 Unicode 數值,如果所給的 Unicode 字符超出了你的 Python 定義範圍,則會引發一個 TypeError 的異常。

描述

ord() 函數是 chr() 函數(對於8位的ASCII字符串)或 unichr() 函數(對於Unicode對象)的配對函數,它以一個字符(長度為1的字符串)作為參數,返回對應的 ASCII 數值,或者 Unicode 數值,如果所給的 Unicode 字符超出了你的 Python 定義範圍,則會引發一個 TypeError 的異常。

語法

以下是 ord() 方法的語法:

ord(c)

參數

  • c -- 字符。

返回值

返回值是對應的十進制整數

實例

以下展示了使用 ord() 方法的實例:

>>>ord(a)
97
>>> ord(b)
98
>>> ord(c)
99

python高階函數,map,filter,reduce,ord,以及lambda表達式