詳解Python中的普通函數和高階函數
什麼是函數
每個語言都有函數,甚至大傢用的Excel裡面也有函數,我們以前學習的數學也很多各種各樣的函數。
Python中的函數也是一樣的。
def f(x): print("參數為:",x) return x
這裡的函數 y = f(x), 在數學中表示為一條斜率為1的直線。
函數的嵌套調用
def z(x): pass def f(x): print("參數為:",x) return z(x)
像這樣,我們在f(x)中調用瞭z(x)函數(這裡使用瞭pass關鍵字,實現先不寫,僅作展示目的)
我們能不能不定義z(x)就定義一個函數調用別的函數呢?
就像實現一個數的平方,函數的‘平方’,大概這個意思。
高階函數
def f(z): return z()
這就是高階函數,f函數需要外界提供一個參數,這個參數必須是一個函數。
在使用f(z)的時候,我們不能給一個f(2), f(3)這樣的值。或者有個函數如d(x)返回非函數值結果,我們不能這樣調用:f(d(1))。
學委準備瞭下面的代碼,從簡單函數逐步演化為高階函數:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/10/24 11:39 下午 # @Author : LeiXueWei # @CSDN/Juejin/Wechat: 雷學委 # @XueWeiTag: CodingDemo # @File : func_demo2.py # @Project : hello def f1(x): return x def f2(x, z=100): return x + z / 10 def f3(x, z=100, *dynamic_args): sum = 0 for arg in dynamic_args: sum += arg return x + z / 10 + sum / 10000.0 def dummy_sum(*args): return 0 def f4(x, z=100, sum_func=dummy_sum): return x + z / 10 + sum_func() / 10000.0 print(f1(100)) print(f2(100, z=50)) print(f3(100, 50, 4, 5, 6)) def sum_g(*dynamic_args): def sum_func(): sum = 0 for arg in dynamic_args: sum += arg return sum return sum_func print(f4(100, 50, sum_g(4, 5, 6)))
這裡我們看到函數f1, f2, f3, f4。
補充一個知識點: *dynamic_args 是一個動態參數,不定長度的參數。
也就是f3明明聲明瞭3個參數,最後我們給瞭5個參數。
這裡f3認為x=100, z=50, dynamic_args = [4, 5, 6]
我們先看看輸出結果:
f3 和f4 看起來結果一樣。
但是性質完整不一樣,讀者可以思考十秒。
f4彈性非常大,因為第三個參數為函數。
高階函數可以幫助我們把計算‘降維’(三維變成二維,二維變一維)。
我們思考一下計算圓形和方形的面積
相信大傢閉著眼都能寫出下面兩個函數:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/10/24 11:39 下午 # @Author : LeiXueWei # @CSDN/Juejin/Wechat: 雷學委 # @XueWeiTag: CodingDemo # @File : func_demo2.py # @Project : hello import math def circle_area(r): return math.pi * r * r def rectangle_area(a, b): return a * b
這是圓形面積的數學公式:
f ( r ) = π ∗ r 2
這是矩形面積的數學公式:
f ( a , b ) = a ∗ b
我們看到這裡有的有1個參數的,有的有兩個的怎麼變成高階函數?
讀者可以思考一會。
下面是代碼:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/10/24 11:39 下午 # @Author : LeiXueWei # @CSDN/Juejin/Wechat: 雷學委 # @XueWeiTag: CodingDemo # @File : func_demo2.py # @Project : hello import math def circle_area(r): return math.pi * r * r def rectangle_area(a, b): return a * b def area(x, linear, factor): return x * linear(x, factor) def relation(x, factor): return x * factor a = 10 b = 20 print("長方形面積:", rectangle_area(a, b)) print("圓形面積:", circle_area(a)) print("長方形面積:", area(a, relation, factor=b / a)) print("圓形面積:", area(a, relation, factor=math.pi))
結果如下圖:
這隻是一種解法。
從代碼可以看到,我們把圓形和矩形都看作某一個參照物(半徑/一條邊)的平方,再成乘以一個系數。
下面,我們把正方形面積計算加上:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/10/24 11:39 下午 # @Author : LeiXueWei # @CSDN/Juejin/Wechat: 雷學委 # @XueWeiTag: CodingDemo # @File : func_demo2.py # @Project : hello import math def circle_area(r): return math.pi * r * r def square_area(a): return a * a def rectangle_area(a, b): return a * b def area(x, linear, factor): return x * linear(x, factor) def relation(x, factor): return x * factor a = 10 b = 20 print("長方形面積:", rectangle_area(a, b)) print("正方形面積:", square_area(a)) print("圓形面積:", circle_area(a)) print("長方形面積:", area(a, relation, factor=b / a)) print("正方形面積:", area(a, relation, factor=1)) print("圓形面積:", area(a, relation, factor=math.pi))
上面的代碼執行結果如下:
這就是高階函數的神奇之處,我們從正方形的角度思考。
隻用一個area函數和relation函數,這兩個函數都不必修改,隻需要給一個factor(經驗因子),就能快速計算它的面積。
為何高階函數能夠降低維度
從上面距離的計算面積的函數,我們可以看到計算圓形和長方形,都能看成一個一維函數。
然後以正方形面積為參照物,快速估算出圓形和方形的面積。
當然上面的計算圓形面積采用瞭半徑,還不夠直觀,讀者可以自行改為直徑,這樣factor = math.pi / 4。
這樣在感受上會更貼切。
總結
除瞭上面介紹的函數,參數,高階函數。我們還可以使用lambda函數:
lambda 參數1, 參數2,。。。,第n個參數 : 計算表達式
上面的函數relation函數可以省略不寫,最後調用改為:
print("長方形面積:", area(a, lambda x, f: x * f, factor=b / a)) print("正方形面積:", area(a, lambda x, f: x * f, factor=1)) print("圓形面積:", area(a, lambda x, f: x * f, factor=math.pi))
本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!