本文對 Python 中的函數式程式設計技術進行了簡單的入門介紹。
頭等函數
在 Python 中,函數是「頭等公民」(first-class)。也就是說,函數與其他資料型態(如 int)處於平等地位。
因而,我們可以將函數賦值給變量,也可以將其作為參數傳入其他函數,將它們儲存在其他資料結構(如 dicts)中,並將它們作為其他函數的返回值。
把函數當作物件
由於其他資料型態(如 string、list 和 int)都是對象,那麼函數也是 Python 中的對象。我們來看範例函數 foo,它將自己的名稱列印出來:
def foo(): print("foo")
由於函數是對象,因此我們可以將函數 foo 賦值給任意變量,然後呼叫該變數。例如,我們可以將函數賦值給變數 bar:
bar = foo bar() #will print "foo" to the console
語句 bar = foo 將函數 foo 引用的物件賦值給變數 bar。
把物件當作函數
當物件可呼叫時(callable),它們與函數一樣,如 object()。這是透過 call 方法實現的。
範例如下:
class Greeter: def __init__(self, greeting): self.greeting = greeting def __call__(self, name): return self.greeting + " " + name
每次配置 Greeter 類別的物件時,我們都會建立一個新的對象,也就是打招呼時可以喊的新名字。如下圖:
morning = Greeter("good morning") #creates the callable object morning("john") # calling the object #prints "good morning john" to the console
我們可以呼叫 morning 物件的原因在於,我們已經在類別定義中使用了 call 方法。為了檢查物件是否可調用,我們使用內建函數 callable:
callable(morning) #true callable(145) #false. int is not callable.
資料結構內的函數
函數和其他物件一樣,可以儲存在資料結構內部。例如,我們可以建立 int to func 的字典。當 int 是待執行步驟的簡寫時,這就會派上用場。
# store in dictionary mapping = { 0 : foo, 1 : bar } x = input() #get integer value from user mapping[x]() #call the func returned by dictionary access
類似地,函數也可以儲存在多種其他資料結構中。
把函數當作參數和回傳值
函數也可以當作其他函數的參數和回傳值。接受函數作為輸入或傳回函數的函數叫做高階函數,它是函數式程式設計的重要組成部分。
高階函數具備強大的能力。就像《Eloquent JavaScript》中解釋的:
「高階函數允許我們對動作執行抽象,而不只是抽象數值。」
我們來看一個例子。假設我們想要對一個項目清單(list of items)執行迭代,並將其順序列印出來。我們可以輕鬆建立一個 iterate 函數:
def iterate(list_of_items): for item in list_of_items: print(item)
看起來很酷吧,但這只不過是一級抽象而已。如果我們想在對清單執行迭代時進行列印以外的其他操作要怎麼做呢?
這就是高階函數存在的意義。我們可以建立函數 iterate_custom,待執行迭代的列表和要對每個項目應用的函數都是 iterate_custom 函數的輸入:
def iterate_custom(list_of_items, custom_func): for item in list_of_items: custom_func(item)
這看起來微不足道,但其實非常強大。
我們已經把抽象的層級提升了一層,讓程式碼具備更強的可重用性。現在,我們不僅可以在列印清單時呼叫該函數,還可以對涉及序列迭代的清單執行任意操作。
函數還能被傳回,使事情變得更加簡單。就像我們在 dict 中儲存函數一樣,我們也可以將函數作為控制語句,來決定適合的函數。例如:
def add(x, y): return x + y def sub(x, y): return x - y def mult(x, y): return x * y def calculator(opcode): if opcode == 1: return add elif opcode == 2: return sub else: return mult my_calc = calculator(2) #my calc is a subtractor my_calc(5, 4) #returns 5 - 4 = 1 my_calc = calculator(9) #my calc is now a multiplier my_calc(5, 4) #returns 5 x 4 = 20.
巢狀函數
函數還可以在其他函數內部,這就是「內部函數」。內部函數在建立輔助函數時非常有用,輔助函數即作為子模組來支援主函數的小型可重複使用函數。
在問題需要特定函數定義(參數類型或順序)時,我們可以使用輔助函數。這種不遵循傳統做法的操作使得解決問題變得更加簡單,範例請參見:
http://www-inst.eecs.berkeley.edu/~cs61a/sp12/lectures/lect4-2x3. pdf。
假設你想定義一個斐波那契函數 fib(n),函數只有一個參數 n,我們必須傳回第 n 個斐波那契數。
定義此類函數的一個可行方式是:使用輔助函數來追蹤斐波那契數列的前兩個項(因為斐波那契數是前兩個數之和)。
def fib(n): def fib_helper(fk1, fk, k): if n == k: return fk else: return fib_helper(fk, fk1+fk, k+1) if n <= 1: return n else: return fib_helper(0, 1, 1)
將該計算從函數主體移到函數參數,這具備非常強大的力量。因為它減少了遞歸方法中可能出現的冗餘計算。
單一表達式函數(Lambda 表達式)
如果我們想在未為函數命名之前寫一個函數要怎麼做?如果我們想寫一個簡短的單行函數(如上述範例中的函數 foo 或 mult)要怎麼做?
我们可以在 Python 中使用 lambda 关键字来定义此类函数。示例如下:
mult = lambda x, y: x * y mult(1, 2) #returns 2
该 mult 函数的行为与使用传统 def 关键字定义函数的行为相同。
注意:lambda 函数必须为单行,且不能包含程序员写的返回语句。
事实上,它们通常具备隐式的返回语句(在上面的示例中,函数想表达 return x * y,不过我们省略了 lambda 函数中的显式返回语句)。
lambda 函数更加强大和精准,因为我们还可以构建匿名函数(即没有名称的函数):
(lambda x, y: x * y)(9, 10) #returns 90
当我们只需要一次性使用某函数时,这种方法非常方便。例如,当我们想填充字典时:
import collections pre_fill = collections.defaultdict(lambda: (0, 0)) #all dictionary keys and values are set to 0
接下来我们来看 Map、Filter 和 Reduce,以更多地了解 lambda。
Map、Filter 和 Reduce
Map
map 函数基于指定过程(函数)将输入集转换为另一个集合。这类似于上文提到的 iterate_custom 函数。例如:
def multiply_by_four(x): return x * 4 scores = [3, 6, 8, 3, 5, 7] modified_scores = list(map(multiply_by_four, scores)) #modified scores is now [12, 24, 32, 12, 20, 28]
在 Python 3 中,map 函数返回的 map 对象可被类型转换为 list,以方便使用。现在,我们无需显式地定义 multiply_by_four 函数,而是定义 lambda 表达式:
modified_scores = list(map(lambda x: 4 * x, scores))
当我们想对集合内的所有值执行某项操作时,map 函数很有用。
Filter
就像名称所显示的那样,filter 函数可以帮助筛除不想要的项。例如,我们想要去除 scores 中的奇数,那么我们可以使用 filter:
even_scores = list(filter(lambda x: True if (x % 2 == 0) else False, scores)) #even_scores = [6, 8]
由于提供给 filter 的函数是逐个决定是否接受每一个项的,因此该函数必须返回 bool 值,且该函数必须是一元函数(即只使用一个输入参数)。
Reduce
reduce 函数用于「总结」或「概述」数据集。例如,如果我们想要计算所有分数的总和,就可以使用 reduce:
sum_scores = reduce((lambda x, y: x + y), scores) #sum_scores = 32
这要比写循环语句简单多了。注意:提供给 reduce 的函数需要两个参数:一个表示正在接受检查的项,另一个表示所用运算的累积结果。
以上是一文詳盡 Python 函數式程式設計技術的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python和C 各有優勢,選擇應基於項目需求。 1)Python適合快速開發和數據處理,因其簡潔語法和動態類型。 2)C 適用於高性能和系統編程,因其靜態類型和手動內存管理。

選擇Python還是C 取決於項目需求:1)如果需要快速開發、數據處理和原型設計,選擇Python;2)如果需要高性能、低延遲和接近硬件的控制,選擇C 。

通過每天投入2小時的Python學習,可以有效提升編程技能。 1.學習新知識:閱讀文檔或觀看教程。 2.實踐:編寫代碼和完成練習。 3.複習:鞏固所學內容。 4.項目實踐:應用所學於實際項目中。這樣的結構化學習計劃能幫助你係統掌握Python並實現職業目標。

在兩小時內高效學習Python的方法包括:1.回顧基礎知識,確保熟悉Python的安裝和基本語法;2.理解Python的核心概念,如變量、列表、函數等;3.通過使用示例掌握基本和高級用法;4.學習常見錯誤與調試技巧;5.應用性能優化與最佳實踐,如使用列表推導式和遵循PEP8風格指南。

Python適合初學者和數據科學,C 適用於系統編程和遊戲開發。 1.Python簡潔易用,適用於數據科學和Web開發。 2.C 提供高性能和控制力,適用於遊戲開發和系統編程。選擇應基於項目需求和個人興趣。

Python更適合數據科學和快速開發,C 更適合高性能和系統編程。 1.Python語法簡潔,易於學習,適用於數據處理和科學計算。 2.C 語法複雜,但性能優越,常用於遊戲開發和系統編程。

每天投入兩小時學習Python是可行的。 1.學習新知識:用一小時學習新概念,如列表和字典。 2.實踐和練習:用一小時進行編程練習,如編寫小程序。通過合理規劃和堅持不懈,你可以在短時間內掌握Python的核心概念。

Python更易學且易用,C 則更強大但複雜。 1.Python語法簡潔,適合初學者,動態類型和自動內存管理使其易用,但可能導致運行時錯誤。 2.C 提供低級控制和高級特性,適合高性能應用,但學習門檻高,需手動管理內存和類型安全。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),