本篇文章為大家帶來了關於python的相關知識,其中主要介紹了函數式程式設計的相關問題,也就是在命令式範式中,透過為電腦提供一系列指令然後執行它們來完成任務,希望對大家有幫助。
推薦學習:python學習教學
在這篇文章裡,你將學會什麼是函數範式以及如何使用Python進行函數式編程。你也將了解列表推導和其它形式的推導。
在命令式範式中,透過為電腦提供一系列指令然後執行它們來完成任務。在執行這些指令時,可以改變某些狀態。例如,假設你最初將A設為5,然後改變A的值。這時在變數內部值的意義上,你改變了A的狀態。
在函數式範式中,你不用告訴電腦做什麼而是告訴他這個東西是什麼。例如數字的最大公約數是什麼,從1到n的乘積是什麼等等。
因此,變數不能變化。一旦你設定了一個變量,它就永遠保持這種狀態(注意,在純函數式語言中,它們不是變量)。因此,函數式程式設計沒有副作用。副作用指的是函數改變它自己以外的東西。讓我們來看一些典型Python程式碼的範例:
這段程式碼的輸出是5。在函數式範式中,改變變數是一個很大的禁忌,並且具有影響其範圍之外事物的功能也是一個很大的禁忌。函數唯一能做的就是計算一些東西並將其作為結果傳回。
現在你可能會想:「沒有變量,沒有副作用?為什麼這樣好?」這個問題問得好,我相信大多數人對此感到疑惑。
如果使用相同的參數呼叫函數兩次,則保證會傳回相同的結果。如果你已經學習了數學函數,你就會知道這個好處。這稱為參照透明度。由於函數沒有副作用,如果你正在建立一個計算某些事情的程序,你可以加速程序。如果每次呼叫func(2)都回傳3,我們可以將它儲存在表中,這可以防止程式重複執行相同的功能。
通常,在函數式程式設計中,我們不使用迴圈。我們使用遞歸。遞歸是一個數學概念,通常意味著“自我調用”。使用遞歸函數,該函數將其自身作為子函數重複呼叫。這是Python中遞迴函數的一個很好的例子:
有些程式語言也具有惰性。這意味著他們直到最後一秒才計算或做任何事情。如果你寫一些程式碼來執行2 2,函數程式只會在你真正需要使用結果時計算出來。我們很快就會在Python中探索惰性。
為了理解,我們先來看看迭代是什麼。通常可以迭代的物件是列表或數組,但Python有許多不同的類型可以迭代。你甚至可以創建自己的對象,這些對象可以透過實現魔術方法進行迭代。魔術方法就像是一個API,可以幫助你的物件變得更Pythonic。您需要實現2個魔術方法才能使對象成為可迭代的:
第一個魔術方法“__iter__”(註:這裡是雙下劃線)返回迭代對象,這通常在循環開始時使用。 ”__next__「傳回下一個物件。
讓我們快速進入一個終端呼叫上面的程式碼:
#運行將會印出
在Python中,迭代器是一個只有__iter__魔術方法的物件。這意味著您可以存取物件中的位置,但不能遍歷該物件。有些物件將具有魔術方法__next__而不是__iter__魔術方法,例如集合(在本文後面討論)。對於本文,我們假設我們接觸的所有內容都是可迭代的物件。
現在我們知道什麼是可迭代物件了,讓我們回到map函數。 map函數允許我們將函數應用於iterable中的每一項。 Map需要2個輸入,它們分別是要套用的函數和可迭代物件。
假設我們有一個數字列表,如下所示:
我們想要對每個數字進行平方,我們可以寫如下程式碼:
Python中函數式的函數是具有惰性的。如果我們不使用“list”,函數將儲存iterable的定義,而不是列表本身。我們需要明確告訴Python「把它變成一個清單」供我們使用。
在Python中突然從非惰性求值轉向惰性求值有點奇怪。如果你在函數式思維方式中考慮得更多,而不是命令式思維方式,那麼你最終會習慣它。
現在寫一個像「square(num)」這樣的普通函數雖然很好,但卻是不對的。我們必須定義一個完整的函數才能在map中使用它?好吧,我們可以使用lambda(匿名)函數在map中定義一個函數。
lambda表達式是一個只有一行的函數。舉個例子,這個lambda表達式對給定的數字平方:
#讓我們運行它:
# #這看起來不像函數嗎? 嗯,這有點令人困惑,但可以解釋。我們將一些東西分配給變數“square”。那這個呢: 告訴Python這是一個lambda函數,輸入叫做x。冒號之後的任何內容都是您對輸入所做的操作,它會自動傳回結果。 簡化我們的square程式到只有一行程式碼,我們可以這樣做: 所以在lambda表達式中,所有參數都在左邊,你要用它們做的東西在右邊。它有點亂。但事實是,編寫只有其他函數式程式設計師才能閱讀的程式碼會有一定的樂趣。此外,使用函數並將其轉換為一行程式碼是非常酷的。##開頭我說過純函數式程式語言沒有變數。更高階的函數使這變得更容易。
Python中的所有函數都是一等公民。一等公民被定義為具有以下一個或多個特徵:
在運行時創建
在資料結構中分配變數或元素
作為函數的參數傳遞
作為函數的結果傳回
Python中的所有函數都可以用作高階函數。
Partial application(也稱為閉包)有點奇怪,但非常酷。您可以在不提供所需的所有參數的情況下呼叫函數。讓我們在一個例子中看到這一點。我們想要建立一個函數,它接受2個參數,一個基數和一個指數,並且傳回指數冪的基數,如下所示:
##現在我們想要一個專用的平方函數,使用冪函數計算數字的平方: 這有效,但如果我們想要一個立方體函數呢?或者求四次方的功能呢?我們可以繼續寫下它們嗎?好吧,你可以。但程式設計師很懶的。如果你一遍又一遍地重複同樣的事情,這表明有一種更快的方法來加快速度,這將使你不再重複。我們可以在這裡使用閉包。讓我們來看一個使用閉包的square函數的範例: 是不是很酷!我們可以只使用1個參數來呼叫需要2個參數的函數。 我們也可以使用一個迴圈來產生一個冪函數,該函數實作從立方體一直到1000的冪。你可以為任何可迭代物件建立一個推導。
可以使用推導產生任何可迭代的物件。從Python 2.7開始,您甚至可以產生字典(hashmap)。
如果它是可迭代的,則可以產生它。讓我們來看看最後一組的例子。
#set是一個元素列表,在該列表中沒有元素重複兩次。
set中的元素沒有順序。
您可能會注意到set(集合)與dict(字典)具有相同的花括號。 Python非常聰明。根據你是否為dict提供值,它會知道你是在寫dict推導還是set推導。
推薦學習:python教學
#以上是一起來分析Python函數式編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!