python 高階函數

1、一等公民

  函數在 Python 是一等公民(First-Class Object)
  函數也是對象,是可調用對象
  函數可以作為普通變量,也可以作為函數的參數、返回值

2、高階函數(High-order Function)

  數學概念 y=f(g(x))
  在數學和計算機科學中,高階函數應當是至少滿足下面一個條件的函數:
    接受一個或多個函數作為參數
    輸出一個函數

# 高階函數,例1:
def counter(base):
    def inc(step=1):             # 局部變量
        nonlocal base
        base += step
        return base
    return inc                   # 局部變量 inc,每次賦值即重新定義

c1 = counter(5)
c2 = counter(5)
print(c1(), c2())                # 6 6
print(c1() == c2())              # True,函數對象的返回值相等
print(counter(5) == counter(5))  # False,函數每次調用都不一樣
# 高階函數,例2:
def
inc(step=1): return step def counter(): return inc # 返回全局變量 inc c1 = counter() c2 = counter() print(c1 == c2) # True,因為全局變量 inc 不消亡

3、自定義 sort 函數

  仿照內建函數 sorted,請自行實現一個 sort 函數(不用使用內建函數),能夠為列表元素排序。

  思考:通過練習,思考 sorted 函數的實現原理,map、filter 函數的實現原理。

  思路:
  內建函數 sorted 函數,它返回一個新的列表,可以設置升序或降序,可以設置一個用於比較的函數(自定義函數也要實現這些功能)
  新建一個列表,遍歷原列表,和新列表中的當前值依次比較,決定帶插入數插入到新列表的什麼位置。

  實現1:實現升序和倒序

def sort(iterable):      # 例:[4, 3, 6]
    target = []
    for x in iterable:
        for i, y in enumerate(target):    # [4]
            if x < y:    # 被插入值小於當前索引值,insert 插入(升序),即當 x > y 時倒序
                target.insert(i, x)
                break    # 找到插入位置,結束當前循環
        else:
            target.append(x)
    return target
print(sort([4, 3, 6]))

  實現2:實現 reverse

def sort(iterable, *, reverse=False):             # 設定 reverse 缺省值為 False,不反轉
    target = []
    for x in iterable:
        for i, y in enumerate(target):
            order = x > y if reverse else x < y   # 通過 reverse 關鍵字傳參,實現 升序、逆序
            if order:
                target.insert(i, x)
                break
        else:
            target.append(x)
    return target
print(sort([4, 3, 6], reverse=True))              # [6, 4, 3]

  實現3:實現 key

def sort(iterable, *, key, reverse=False):
    target = []
    for x in iterable:
        for i, y in enumerate(target):
            order = key(x) > key(y) if reverse else key(x) < key(y)    # key()
            if order:
                target.insert(i, x)
                break
        else:
            target.append(x)
    return target
print(sort([4, 3, '3', 6], reverse=True, key=int))    # [6, 4, 3, '3']

  實現4:實現 key 的缺省值,key=None

def sort(iterable, *, key=None, reverse=False):
    target = []
    for x in iterable:
        for i, y in enumerate(target):
            x = key(x) if key else x
            y = key(y) if key else y
            # 不符合(轉換後的結果只是用來比較大小的,不改變最後生成的列表中的元素本身)!
            # 而且 x 重複計算!
            order = x > y if reverse else x < y
            if order:
                target.insert(i, x)
                break
        else:
            target.append(x)
    return target
print(sort([4, 3, '3', 6], reverse=True, key=str))    # ['6', 4, '3', '3']

# 再改進! def sort(iterable, *, key=None, reverse=False): target = [] for x in iterable: cx = key(x) if key else x # 轉換後的結果只是用來比較大小的,不改變最後生成的列表中的元素本身 for i, y in enumerate(target): cy = key(y) if key else y order = cx > cy if reverse else cx < cy if order: target.insert(i, x) break else: target.append(x) return target print(sort([4, 3, '3', 6], reverse=True, key=str)) # [6, 4, 3, '3']

4、內建高階函數

  排序 sorted

  定義:sorted(iterable, *, key=None, reverse=False) => list

'''
sorted()         # 返回新列表
list.sort()      # 就地修改
'''

lst = [1, 4, 2, 6, 3]
print(sorted(lst, key=lambda x : 7-x))      # 升序,key=lambda x : 7-x,影響排序結果
lst.sort(reverse=True, key=lambda x : 7-x)  # 降序,key=lambda x : 7-x,影響排序結果
print(lst)

# 執行結果:
[6, 4, 3, 2, 1]
[1, 2, 3, 4, 6]

  映射 map

  定義:map(function, *iterables) => map object

  對多個可迭代對象的元素,按照指定的函數進行映射,返回一個迭代器

g = list(map(lambda x : x+1, range(1, 6)))
print(g)    # [2, 3, 4, 5, 6]

g1 = { i:(i, i+1) for i in map(lambda x : x+1, range(1, 6))}
print(g1)   # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)}

g2 = dict(map(lambda x : (x+1, (x+1, x+2)), range(1, 6)))    # 二元組
print(g2)   # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)}

g3 = dict(zip(range(2, 7), map(lambda x : (x, x+1), range(2, 7))))
print(g3)   # {2: (2, 3), 3: (3, 4), 4: (4, 5), 5: (5, 6), 6: (6, 7)}

g4 = dict(map(lambda x, y : [x, y], 'abcde', range(10)))
print(g4)   # {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}

  過濾 filter

  定義:filter(function, iterable)

  對可迭代對象進行遍歷,返回一個迭代器
  function 參數是一個參數的函數,且返回值應當是 bool 類型,或其返回值等效布爾值
  function參數如果是 None,可迭代對象的每一個元素自身等效布爾值

# if element: yield element             # 如果這個元素,則返回這個元素
print(filter(None, range(10)))          # 惰性對象
print(list(filter(None, range(10))))    # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(None, range(-5, 5)))) # [-5, -4, -3, -2, -1, 1, 2, 3, 4]

# if fn(element): yield element
print(list(filter(lambda x : True, range(10))))    # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(lambda x : None, range(10))))    # []
print(list(filter(lambda x : 0, range(10))))       # []

# 如果 x%3==0,則為 True
print(list(filter(lambda x : x%3==0, [1, 9, 55, 150, -3, 78, 28, 123])))
# [9, 150, -3, 78, 123]

 

Tags: