<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文對 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.
函數還可以在其他函數內部,這就是「內部函數」。內部函數在建立輔助函數時非常有用,輔助函數即作為子模組來支援主函數的小型可重用函數。
在問題需要特定函數定義(引數型別或順序)時,我們可以使用輔助函數。這種不遵循傳統做法的操作使得解決問題變得更加簡單。
假設你想定義一個斐波那契函數 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)
將該計算從函數主體移到函數引數,這具備非常強大的力量。因為它減少了遞迴方法中可能出現的冗餘計算。
如果我們想在未給函數命名之前寫一個函數要怎麼做?如果我們想寫一個簡短的單行函數(如上述範例中的函數 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 函數基於指定過程(函數)將輸入集轉換為另一個集合。這類似於上文提到的 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 函數可以幫助篩除不想要的項。例如,我們想要去除 scores 中的奇數,那麼我們可以使用 filter:
even_scores = list(filter(lambda x: True if (x % 2 == 0) else False, scores)) #even_scores = [6, 8]
由於提供給 filter 的函數是逐個決定是否接受每一個項的,因此該函數必須返回 bool 值,且該函數必須是一元函數(即只使用一個輸入引數)。
reduce 函數用於「總結」或「概述」資料集。例如,如果我們想要計算所有分數的總和,就可以使用 reduce:
sum_scores = reduce((lambda x, y: x + y), scores) #sum_scores = 32
這要比寫回圈語句簡單多了。注意:提供給 reduce 的函數需要兩個引數:一個表示正在接受檢查的項,另一個表示所用運算的累積結果。
到此這篇關於Python 入門學習之函數語言程式設計的文章就介紹到這了,更多相關Python 函數語言程式設計 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45