概述
在上一節(jié)苞氮,我們介紹了Python的數據類型湾揽,包括:數字、字符串、列表库物、元組霸旗、集合、字典等內容戚揭。在本節(jié)中定硝,我們將介紹Python的函數。在Python中毫目,函數是一段可以重復使用的代碼塊蔬啡,它可以提高代碼的可重用性和可維護性,是編程中非常重要的概念镀虐。
在C/C++箱蟆、Java等其他編程語言中,基本都存在函數的概念刮便。那么空猜,為什么要使用函數呢?因為函數具有以下優(yōu)點恨旱。
可定制性:函數可以根據需求定制辈毯,以滿足不同的功能需求。
可重用性:函數可以重復使用搜贤,避免重復編寫相同的代碼谆沃。
可維護性:函數可以降低代碼的復雜性,提高代碼的可維護性仪芒。
函數的定義
在Python中唁影,可以使用def關鍵字定義一個函數,其格式如下:
def function_name(parameters):
"""docstring"""
function_body
其中掂名,function_name是函數的名稱据沈,parameters是函數的參數列表,最后面是冒號饺蔑,冒號后面的內容需要縮進锌介。docstring是函數的文檔字符串,用于描述函數的作用和用法猾警。function_body是函數的主體部分孔祸,包含函數的邏輯代碼。
函數的參數放在小括號里面肿嘲,參數可以有一個或多個融击,也可以沒有,多個參數之間使用逗號進行分隔雳窟。
# 沒有參數
def my_print():
print('hello')
# 一個參數
def print_text(text):
print('hello', text)
# 多個參數
def print_sum(x, y):
print('sum:', x + y)
函數可以通過return語句返回一個值。如果函數沒有return語句,或者return語句沒有跟任何值封救,則函數返回默認的None拇涤。
# 不帶return,默認返回None
def test1():
print('hello Hope')
# return沒有跟任何值誉结,默認返回None
def test2():
print('hello world')
return
def Add(x, y):
return x + y
函數的調用
定義函數后鹅士,可以通過函數名加上參數列表的方式調用函數。調用函數時惩坑,將實際參數傳遞給函數的參數列表掉盅。
# 統(tǒng)計文本中的單詞數量
def count_words(text):
words = text.split()
count = len(words)
return count
def show_info(name, age):
print('name is', name, ', age is', age)
# 調用上面定義好的函數
count = count_words('hello Hope')
# 輸出:2
print(count)
# 輸出:name is Mike , age is 16
show_info('Mike', 16)
參數的傳遞
在上一節(jié)我們曾提到,數字以舒、字符串趾痘、元組屬于不可變數據類型,列表蔓钟、集合永票、字典屬于可變數據類型。
當函數的參數為不可變數據類型時滥沫,參數的傳遞與C++中的值傳遞類似侣集。比如:有一個函數func(a),傳遞的只是a的值兰绣,沒有影響a對象本身世分。如果在func(a)內部修改a的值,則是新生成一個a的對象缀辩,修改后func外部的a不會受到影響罚攀。
def test1(a):
# 輸出:66
print(a)
a = 100
# 輸出:100
print(a)
a = 66
test1(a)
# 不可變數據類型,仍然輸出:66
print(a)
當函數的參數為可變數據類型時雌澄,參數的傳遞與C++中的引用傳遞類似斋泄。比如:有一個函數func(a),傳遞的是a的地址镐牺。如果在func(a)內部修改a的值炫掐,修改后func外部的a也會受到影響。
def test1(a):
# 輸出:['C', 'S', 'D']
print(a)
a.append('N')
# 輸出:['C', 'S', 'D', 'N']
print(a)
a = ['C', 'S', 'D']
test1(a)
# 可變數據類型睬涧,輸出:['C', 'S', 'D', 'N']
print(a)
函數的參數主要有五種不同的類型:必需參數募胃、默認參數、不定長參數畦浓、強制關鍵字參數痹束、強制位置參數,下面分別進行介紹讶请。
必需參數:調用時祷嘶,必須傳遞的參數;如果不傳遞,運行時會引發(fā)TypeError異常论巍。必須參數既可以按照位置逐一傳遞烛谊,也可以使用關鍵字指定的方式傳遞(此時不用與定義時的參數順序保持一致)。
def show_info(name, age, gender):
print(f'{name}, {gender}, is {age} years old')
# 輸出:Mike, Male, is 25 years old
show_info('Mike', 25, 'Male')
# 輸出:Tom, Female, is 32 years old
show_info('Tom', gender='Female', age=32)
# 報錯:missing 1 required positional argument: 'gender'
show_info('Jim', 28)
默認參數:定義時嘉汰,參數給定了默認值丹禀;調用時,可以傳遞該參數鞋怀,也可以不傳遞該參數脊串,不傳遞則使用默認值龄减。
def greet(name = 'Hope'):
print(f'Hello, {name}')
# 輸出:Hello, Hope
greet()
# 輸出:Hello, World
greet('World')
不定長參數:在Python中,可以使用兩種方式定義不定長參數。一是使用一個星號()作為參數前綴匾寝,將該參數定義為不定長位置參數哼审;該參數可以接收任意數量的參數毅哗,并將它們打包成一個元組(tuple)傳遞給函數率寡。二是使用兩個星號(*)作為參數前綴,將該參數定義為不定長關鍵字參數废累;該參數可以接收任意數量的關鍵字參數邓梅,并將它們打包成一個字典(dict)傳遞給函數。
# 一個星號的不定長參數
def func1(*args):
for arg in args:
print(arg)
# 依次輸出:66 88 99
func1(66, 88, 99)
# 依次輸出:Hello Hope
func1('Hello', 'Hope')
# 兩個星號的不定長參數
def func2(text, **kwargs):
print(text)
for key, value in kwargs.items():
print(f'{key}: {value}')
# 依次輸出:info: name: Lily age: 16 city: BeiJing
func2('info:', name='Lily', age=16, city='BeiJing')
強制關鍵字參數:只能以關鍵字形式來指定的參數邑滨,從而確保調用該函數的代碼讀起來會比較明確日缨。定義函數時,如果單獨出現星號(*)掖看,則星號后的參數必須用關鍵字傳入匣距。
def my_sum(a, b, *, c):
return a + b + c
# c為強制關鍵字參數,必須以關鍵字方式指定
my_sum(1, 2, c = 3)
# 運行時報錯:my_sum() takes 2 positional arguments but 3 were given
my_sum(1, 2, 3)
強制位置參數:只能以位置形式哎壳,不能以關鍵字形式來指定的參數毅待。定義函數時,如果單獨出現斜杠(/)归榕,則斜杠前的參數必須用位置形式傳入尸红。
def my_sum(a, b, /, c):
return a + b + c
# a、b為強制位置參數刹泄,必須以位置方式指定
my_sum(1, 2, 3)
# 運行時報錯:my_sum() got some positional-only arguments passed as keyword arguments: 'b'
my_sum(1, b = 2, c = 3)
lambda函數
lambda函數是一種沒有函數名稱的匿名函數或小型函數外里,通常用于短小的、臨時性的特石、或者作為高階函數的參數(比如:map()盅蝗、filter()等)。
lambda函數的語法格式為:lambda arguments : expression姆蘸。
其中墩莫,arguments是一個函數參數列表芙委,由一個或多個參數組成,多個參數之間使用逗號進行分隔贼穆。expression是一個表達式题山,當有多個參數時兰粉,表達式中必須使用參數對應的順序故痊。
在下面的例子中,定義了一個lambda函數my_add玖姑,接收兩個參數x和y愕秫,并返回它們的和,最后通過調用my_add(66, 99)來執(zhí)行這個函數焰络。
my_add = lambda x, y: x + y
# 輸出:165
print(my_add(66, 99))
再來看看在高階函數filter中使用lambda函數的例子戴甩。
data = [12, 25, 7, 32, 21]
# 找出列表中所有大于20的數
result = filter(lambda x: x > 20, data)
# 輸出:[25, 32, 21]
print(list(result))
總結一下,lambda函數具有以下優(yōu)點:
語法簡潔:lambda函數使用簡潔的語法闪彼,可以在一行代碼中定義簡單的函數甜孤。
匿名函數:lambda函數是匿名函數,不需要指定函數名稱畏腕,這使得它們可以作為臨時函數在代碼中快速定義缴川。
短小函數:lambda函數通常定義的是短小的函數,這使得它們在處理簡單的任務時非常方便描馅。
高階函數參數:lambda函數常作為高階函數的參數把夸,這使得它們可以與其他函數配合使用,實現更加靈活和定制化的操作铭污。
提高代碼可讀性:在一些情況下恋日,使用lambda函數可以使代碼更加簡潔、易于理解嘹狞。
提高執(zhí)行效率:與普通函數相比岂膳,lambda函數的執(zhí)行效率更高。
不過需要注意的是磅网,雖然lambda函數在某些情況下非常有用谈截,但在處理復雜任務或需要重復使用的功能時,還是建議使用完整的函數定義知市。