Python 函数式编程指北,不只是面向对象哦
了解在Python中如何使用 lambda, map, filter 和 reduce 函數來轉換數據結構
Photo by Markus Spiske on Unsplash
面向對象的編程通過封裝移動部件來讓代碼變得易于理解,而函數式編程則通過盡量減少移動部件來使代碼變得易于理解?!?Michael Feathers
世界上有很多種語言,它們可以歸類的類別也是如此。編程示例是一種基于編碼風格和語言方式去嘗試把不同語言分類的途徑。編程示例本質上就是一種風格和編程方式。
大多數的時候,我們認為 Python 是面向對象語言, 我們以 類(classes),對象(objects),和方法(methods)對數據進行模擬。但是,OOP 也有幾種替代方案,函數式編程就是其中之一。
以下是業界流行的一些傳統編程示例:
常規編程示例:來源 Wikipedia
1、函數式編程(FP)
函數式方程示例
根據維基百科, 函數式方程 是一種函數式示例, 是構建計算機程序結構和基本要素的一種風格。它將計算視為數學函數的評估和避免改變數據和其狀態。
上面的定義有可能一開始聽起來很讓人迷惑,但它基本上試圖提出以下觀點:
- FP 依賴于方程,一切都是使用函數來完成的。并且,FP 專注于定義去做什么,而不是執行某些操作。這種函數示例被認為是一級函數式。這意味著函數被視為任何其它對象,我們可以把他們分配給變量或者將他們嵌入其它函數式。
- 函數式使用的數據必須是不可變的。這意味著如果我們需要修改列表中的數據,我們需要新建一個包含更新值的新列表,而不是操縱現有的列表。
- 寫入FP的程序應該是無狀態的。無狀態的方程式不能表達其過去狀態。函數式編程每一次執行任務,就像他們第一次執行一樣。簡而言之,這些函數僅依賴于作為參數傳遞給他們的數據,而不依賴于外部數據。
- 惰性是 FP 另外一個特性,我們不需要計算我們不需要的東西,工作只在需要時完成。
如果現在有所了解,下面是 OOP 和 FP 很好的對比圖表,這將概念變得更明顯。
圖片來源: www.educba.com
Python提供了 lambda,filter,map 和 reduce 等功能,可以輕松演示函數式編程的概念??梢詮年P聯的 Github 存儲庫 訪問本文中使用的所有代碼.
https://github.com/parulnith/Elements-of-Functional-Programming-in-Python
2、Lambda 表達式
Lambda 表達式 - 也稱為“匿名函數” - 允許我們在一行中創建和使用函數。當我們需要一個只能使用一次的短函數時它們很有用。它們主要與 map,filter 和 sort 方法結合使用,我們將在本文后面講到。
讓我們用 Python 編寫一個函數來計算 5x + 2. 標準的做法是定義一個函數。
現在讓我們使用 Lambda 函數計算相同的表達式。要創建 lambda 表達式,我們輸入關鍵字 lambda,后面輸入函數。接下來,我們輸入一個冒號,后面是返回值的表達式。
這個 lambda 函數將獲取輸入 x 并返回 5x + 2,就像之前的函數一樣 f 。但是,有一個問題。Lambda 不是函數的名稱。它是一個 Python 關鍵字,表示接下來是一個匿名函數。那么我們如何使用它呢?一種方法是給它起一個名字。
讓我們稱之為 lambda 表達式 g?,F在,我們可以像任何其他功能一樣使用它。
具有多個輸入值的Lambda表達式
下面的示例顯示了lambda函數如何在有或沒有輸入值的情況下使用。
沒有輸入值的Lambda表達式
現在,讓我們看看 Lambda 函數的常見用法,我們不為它指定名稱。假設我們列出了前七位美國總統的名單,我們想用他們的姓氏對這份名單進行排序。我們將創建一個提取姓氏的 Lambda 函數,并將其用作排序值。
map,filter 和 reduce 函數簡化了使用列表的工作。與 lambda 表達式一起使用時,它們通過在一行代碼中完成大量工作,有助于使我們的生活更輕松。
3、Map 函數
Map 函數對每一個數值進行迭代并產生的結果。與列表一起使用時,Map通過將函數應用于在input_list中的所有值,將給定列表轉換為新列表。
句法
map(function_to_apply, iterables)用法
假設我們有一個函數來計算一個立方體的體積,給定它的邊長 a
def volume(a): """volumne of a cube with edge 'a'""" return a**3如果我們需要計算具有不同邊長的不同立方體的體積,該怎么辦?
# Edge length in cmedges = [1,2,3,4,5]有兩種方法可以做到這一點, 一種是使用直接方法,另一種是使用 map 函數。
現在讓我們看看如何使用 map 函數使用一行代碼來完成此任務。
Map 函數有兩個參數。第一個是函數,第二個是我們的 list ,tuple 或任何其他可迭代對象。這里,map 函數將 volume 函數應用于列表中的每個元素。
這里要注意的一件重要事情是 map 函數的輸出不是列表而是 map 對象,它是結果的迭代器。但是,我們可以通過將映射傳遞構造列表將其轉換為列表。
例子
現在讓我們看一個演示 lambda 函數與 map 函數一起使用的例子。我們有一個包含 5 個人姓名和高度的元組列表。每個高度都以厘米為單位,我們需要將其轉換為英尺。
我們將首先使用 lambda 表達式編寫轉換器函數,該表達式將接受元組作為輸入,并且還將返回元組
4、Filter 函數
Filter 函數從可迭代元素中構造一個迭代器,并且函數返回符合值。這意味著 filter 函數用于從 list,tuple 或其他數據集合中選擇某些數據,因此叫這個名字。
句法
filter(function, iterable)用法
讓我們看一個例子,我們想要從給定的輸入列表中獲取大于 5 的所有數字的列表。
我們首先創建一個lambda函數來測試輸入,看它是否大于5。接下來,我們傳入數據列表。Filter 函數僅返回函數為正確的數據。再一次,返回值不是列表,而是 filter 對象。必須將此對象傳遞給列表構造函數才能獲得輸出。
例子
一個有趣的例子,當數據由缺失值組成時,filter 函數發生作用。這是一份包含亞洲一些國家的清單。注意很多字符串都是空的。我們將使用 filter 功能來刪除這些缺失值。我們將空集作為第一個參數,第二個參數是剛剛提到的數據列表。
這會過濾掉布爾設置中被視為否的所有值。
5、Reduce 函數
Reduce 功能有點不尋常,從 Python 3 開始,它不再是內置函數。相反,它已被移動到 functools 模塊。 reduce 函數通過將給定列表轉換為單個值,通過列表中值從左到右順序累加并返回一個值。
用法
reduce(func, seq)reduce 持續將函數 func() 應用于序列 seq 并返回單個值。
用法
讓我們通過一個計算整數列表連乘的簡單例子來說明 reduce 函數的工作原理。
下圖顯示了計算的中間步驟:
在 Python 中使用 Reduce 函數
然而,Python 的創建者 Guido van Rossum 不得不對 Reduce 函數這樣說:
如果你確實需要,請使用 functools.reduce; 但是,99% 的時間表明 for 循環更具有可讀性。
上面的程序也可以使用顯式的 for 循環編寫:
例子
Reduce 函數可以用單行代碼找出整數列表中的最大值。確實在 Python 中存在一個內置函數 max(),它也通??梢杂糜诖四康?max(list_name)。
6、列表推導式: 替代 map, filter 和 reduce
列表推導式(list comprehensions) 是一種在Python 中定義和創建列表的方法。在大多數情況下,列表理解使我們可以在一行代碼中創建列表,而無需擔心初始化列表或設置循環。
它也是 lambda 函數以及函數 map(),filter()和reduce()的替代品。有些人發現它是一種更加體現 python 的編寫函數的方式,并且發現它更容易理解。
句法
用法
讓我們嘗試用 列表推導式來演示上面部分使用的示例。
- 列表推導式 vs. Map 函數
我們將 map 函數與 lambda 函數結合使用,將高度列表從 cm 轉換為英尺。讓我們使用列表推導式來實現相同的結果。
- 列表推導式 vs. Filter 函數
我們使用過濾功能從亞洲國家/地區列表中刪除缺失值。讓我們使用列表推導式來獲得相同的結果。
- 列表推導式 vs. Reduce 函數
類似地,我們可以使用列表推導式來快速確定包含整數列表的最大值,而不是使用 lambda 和 reduce。
我們在上面例子中使用了相應函數式表達,類似于列表推導式,但是使用圓括號而不是方括號。
7、結論
Map,Filter 和 Reduce 函數顯著簡化了使用列表和其他可迭代數據集的過程。有些人對使用它們有所保留,特別是因為列表推導式似乎更友好,但它們的用處不容忽視。
總結
以上是生活随笔為你收集整理的Python 函数式编程指北,不只是面向对象哦的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 命令行之旅:深入 clic
- 下一篇: 警告!你的Python代码命名太烂了,命