1. 程式人生 > >Python函數式編程

Python函數式編程

生成 IV python語言 檢查 trace 參數 返回 二進制 結果

## 高階函數
  - 接受函數為參數的函數稱為高階函數

def fn(num):       # 接收參數並打印
    print(num)

def run_fn(fn, num): # 接受函數為參數
    fn(num) # 執行

run_fn(fn, 10)      # 10

  - 在Python中函數名也是變量,函數體就是這個變量的值,是變量就可以重新賦值,取代原有綁定

def fn(num):     # 定義一個函數
    print(num)

fn(10)       # 執行函數,輸出10

fn = 10        #
給函數名即變量fn重新賦值,解除fn與函數體的綁定 fn(10)    # fn不指向函數體,無法調用 """ Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: ‘int‘ object is not callable # 報錯,類型錯誤:整型對象無法被調用 """

## 常用內建高階函數

  - map(fn, iterable)
    - 此函數接受兩個參數,第一個參數為函數,第二個參數為可叠代對象
    - map()函數執行時,將可叠代對象參數中逐一取出一個值作為參數傳入第一個函數參數並執行該參數函數      

def fn(n):
    return n * n
    
map(fn, [1, 2, 3])       # 計算列表元素的平方
# <map object at 0x7f5ee58e5b00>

list(map(fn, [1, 2, 3]))
# [1, 4, 9]

list(map(str, [1, 2, 3]))  # 將列表中所有值都轉換為字符串
# [‘1‘, ‘2‘, ‘3‘]

  - reduce(fn, iterable),使用前需要從functools導入
    - 此函數接受兩個參數,第一個參數為函數,第二個參數為可叠代對象

    - 將第二個參數的元素按照第一個參數函數的語句逐一累積為一個值,並返回結果

from functools import reduce

def add(a, b):
    return a + b
    
reduce(add, [1, 2, 3, 4])     # 相當於(((1 + 2) + 3) + 4)
# 10    

  - filter(fn, iterable)
    - 過濾器
    - 將第二個參數的元素按照第一個參數函數的條件逐一檢查,若參數函數返回True,則保留該元素,否則則舍去該元素

def even(n):
    if n % 2 == 0:
        return True
    return False
    
filter(even, [1, 2, 3, 4, 5, 6])
# <filter object at 0x7f57c68cc550>

list(filter(even, [1, 2, 3, 4, 5, 6]))
# [2, 4, 6]

  - sorted():排序

numbers = [-50, -43, 23, 188, 20]
sorted(numbers, key=abs)         # 按照絕對值大小排序
# [20, 23, -43, -50, 188]
sorted(numbers, key=abs,reverse=True)  # 排序後反序
# [188, -50, -43, 23, 20]

  - functools.partial():偏函數(Partial function)
    - 以原有函數為基礎,添加常用關鍵字參數生成新函數

import functools

# 創建將二進制數字字符串轉換為十進制整型的新函數
int2 = functools.partial(int, base=2) 

int2("10000000")
# 128

## 內部函數
  - Python允許在函數內部定義函數

def outer(name):
    def inner():
        return "Hi, {0}".format(name)
    return inner()
    
outer("Stanley")
# ‘Hi, Stanley‘

## 閉包
  - 內部函數可以看作一個閉包,閉包是一個可以由另一個函數動態生成的函數,並且可以改變和存儲函數外創建的變量的值

def times(num):
    def inner(a):
        return num * a  # 內部函數可以使用外部函數的值
    return inner     # 返回內部函數
    
times10 = times(10)     # 動態生成一個參數乘10的函數
type(times10)
# <class ‘function‘>

>>> times10(5)
# 50

times5 = times(5)     # 動態生成一個參數乘10的函數
times5(5)
# 25

## 匿名函數:lambda()函數
  - lambda函數是用一條語句表達的匿名函數,可以用來代替短小的函數
    - 語法:
      lambda 參數: 返回值

lambda x: x * 2 

    相當於:

def double(x):
    return x * 2

  - 之前的高階函數也可一直接使用lambda作為參數傳遞

list(map(lambda x: x * 2, [1, 2, 3, 4]))
# [2, 4, 6, 8]

本文參考:
[美]Bill Lubanovic 《Python語言及其應用》
https://www.liaoxuefeng.com 廖雪峰的官方網站

Python函數式編程