簡析Python函數式編程字符串和元組及函數分類與高階函數
函數式編程中的字符串
在函數式編程中,經常用到 Python 字符串,因其是不可變數據結構。
字符串本身是一個對象,具備很多對象方法,與常識中函數的使用不太相同,例如下述代碼
my_str = "xiangpica" print(my_str.upper()) print(len(my_str.upper()))
其中 len()
函數的用法被稱為前置寫法,而 my_str.upper()
被稱為後置寫法,這樣很容易造成函數式編程的理解問題,所以需要系統性的解決該問題。
如果上述代碼可以修改為 len(upper(my_str))
,就變得相對容易理解。
# 類型 Text 是 str 的別名 from typing import Text my_str = "xiangpica" def upper(str: Text) -> Text: return str.upper() print(upper(my_str)) print(len(upper(my_str)))
上述代碼重新定義瞭一個前置用法的函數 upper
,用於解決函數式編程中的一致性問題,該解決辦法在後續代碼中會經常出現。
不變類型元組
除字符串外,Python 中的另一個不可變數據類型為元組,元組分為普通元組與命名元組。
普通元組的聲明與訪問
在之前的文章中對元組的基本知識,已經進行瞭說明,可以去稍微復習一下,然後在進入本文的學習。
先看一下代碼,然後再判斷是否可以理解。
from typing import Tuple, Text, Callable LANGUAGE = Tuple[Text, Text, Text] python: Callable[[LANGUAGE], Text] = lambda languages: languages[1] items = ("c","python","js") a = python(items) print(a)
上述代碼定義瞭一個新的類型 LANGUAGE
,該類型是一個元組,具備三個元素。
python
類型註解是 Callable[[LANGUAGE], Text]
,即它的參數是 LANGUAGE
類型,返回值是字符串類型。
註意 typing
模塊加入不會影響程序的運行不會報正式的錯誤,僅作為類型檢查,防止運行時出現參數、返回值類型不符,開發人員查閱。
除上述內容外,還可以使用命名元組來實現。
from collections import namedtuple Language = namedtuple("Language",("name1", "name2", "name3")) l = Language("c", "python", "js") print(l) print(l.name1)
或者直接使用 typing
模塊的 NamedTuple
也可以。
from typing import NamedTuple, Text class Language(NamedTuple): name: Text description: Text l = Language("C", "C語言") print(l) print(l.name) print(l.description)
函數式的分類
函數大類分為兩種:
- 標量函數:函數的返回結果為一個值;
- 集合函數:函數的結果為可迭代的集合。
集合函數也可以細分:
- 規約/累積函數:將集合內的元素進行累積計算,最後得到一個值;
- 映射函數:將標量函數應用於幾個的每個元素,最後得到一個與原集合相同長度的新集合;
- 過濾函數:將標量函數應用於每個元素,保留一部分,得到一個子集。
有瞭上述概念之後,對於函數式編程的理解可以更進一步。
any() 、all() 、len()、sum() 對比學習
any
與 all
兩個函數屬於規約函數,進行的操作叫做佈爾規約,即將一個集合的元素歸約為 True 或者 False,all
需要所有值都是 True,any
隻要有一個值是 True 即可。
len
與 sum
也是歸約函數,它們分別表示計算集合中所有值的個數和匯總值。
zip()、reversed()、enumerate()
zip
函數可以把多個可迭代對象或者序列,之間的數據進行交叉組合,即將 n 個元素的可迭代對象轉換為 n 元組,然後返回一個生成器。
如果 zip
函數沒有輸入參數,那將返回一個空列表 []
。
a = zip() print(list(a))
reversed
函數用於改變序列順序,即反轉序列。
enumerate
函數獲取序列或者可迭代對象的下標值,轉換成概念描述就是將可迭代對象映射為二元組序列(帶上序號瞭),每個二元組序列中,第一個元素是下標值,第二個元素是值本身。
高階函數
學習 Python 函數式編程,繞不開高階函數的學習,高階函數就是以函數為參數,或者以返回值為函數的函數。
函數 max 和 min()
上述兩個函數是規約函數,即輸入的是集合,輸出的是單個值,主要用途就是尋找極值。
一般在學習的時候,可以把二者當成普通的函數,也可用於高階函數,主要為參數位置的差異。
最簡單的用法為:
max_num = max(1, 2, 3, 4) min_num = min(1, 2, 3, 4) print(max_num) print(min_num)
接下來就是其高階函數模式的實現,自定義比較規則。
# 第一種寫法,比較字符串長度 max_num = max("a", "abc", "ceda", "aaaaa", key=lambda x: len(x)) min_num = min("a", "abc", "ceda", "aaaaa", key=lambda x: len(x)) print(max_num) print(min_num) # 第二種寫法,比較字符串長度 max_num = max(["a", "abc", "ceda", "aaaaa"], key=lambda x: len(x)) min_num = min(["a", "abc", "ceda", "aaaaa"], key=lambda x: len(x)) print(max_num) print(min_num)
上述代碼的 key
為可選參數,默認值為 None。
map 函數
map
函數用於將一個集合映射到另一個集合,例如可以將一個由字符串組成的列表中的每一項,都轉換為整數。
data = ["1", "2", "3"] print(map(int, data)) print(list(map(int, data)))
代碼 map(int, data)
的含義就是將 int
函數作用於 data
中的每一項。
map
函數的第一個參數也可以用 lambda
代替。
data = ["1", "2", "3"] print(map(lambda x: int(x), data)) print(list(map(int, data)))
filter 函數
filter
函數主要用於將一個**判定函數(謂語函數)**用於集合的每一個元素,最後得到滿足判定函數的結果集,測試代碼如下:
data = [1, 3, 5, 7, 9] print(filter(lambda x: x > 3, data)) print(list(filter(lambda x: x > 3, data)))
sorted 函數
sorted
函數也支持高階函數 key
參數定制規則。
result = sorted(["afghsss", "abc", "ceda", "aaaaa"], key=lambda x: len(x)) print(result)
同一需求的不同效率問題
通過 map
函數,生成器表達式,存在迭代器的生成器函數分別多 一億 數據量的列表進行測試。
import time def demo(x): return x * 2 def demo1(f, l): for x in l: yield f(x) my_list = list(range(1, 10000000)) start = time.perf_counter() # map(lambda x: x * 2, my_list) # 程序運行耗時 3.904999999998493e-06 # (demo(x) for x in my_list) # 程序運行耗時 6.310000000009364e-06 demo1(demo, my_list) # 程序運行耗時 5.1070000000041915e-06 cost_time = time.perf_counter() - start print("程序運行耗時", cost_time)
得到的結果是 map
最快,所以用就完事瞭。
以上就是簡析Python函數式編程字符串和元組及函數分類與高階函數的詳細內容,更多關於Python函數式編程的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Python 中的反轉字符串reversed(),切片
- 一文帶你解密Python可迭代對象的排序問題
- 10個必須要掌握的Python內置函數
- 22個Python的萬用公式分享
- Python進階之高級用法詳細總結