本文對 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 的函数需要两个参数:一个表示正在接受检查的项,另一个表示所用运算的累积结果。
本文是关于函数式编程的一篇入门文章,虽然尽量完备地介绍了相关的知识,但并不是那么深入。如想了解更多,大家可以阅读以下资源:
- Best Practices for Using Functional Programming in Python:https://kite.com/blog/python/functional-programming/
- Functional Programming Tutorials and Notes:https://www.hackerearth.com/zh/practice/python/functional-programming/functional-programming-1/tutorial/
以上是Python 函數式編程,看這篇就夠了!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。