Python for循環(huán)如何更加Pythonic
討論了不同的Python編程策略,包括優(yōu)化嵌套結(jié)構(gòu)代碼,列表推導式和生成器表達式的使用,map和reduce函數(shù)的應(yīng)用以及高效使用多函數(shù)并在適當?shù)牡胤绞褂脙?nèi)建庫。
為何需避免循環(huán)?
面對這個問題,可能會有疑慮,為何要對自己的編程提出挑戰(zhàn),盡量避免在代碼中使用for循環(huán)?實際上,要避免在Python里使用for循環(huán),并不是因為for循環(huán)差勁或低效。相反,這是一種通過探索其他結(jié)構(gòu)和功能以深化對Python理解的方式,也能讓代碼更加簡潔、易讀和更"Python"。
通常,for循環(huán)用于以下場景:
- 從序列中提取特定信息。
- 從當前序列創(chuàng)建新序列。
- 使用for循環(huán)已經(jīng)成為習慣。
好消息是,Python 為這些任務(wù)提供了一系列工具,只需要改變思考方式并獲得新的視角就可以解決它們。
避免編寫for循環(huán),您可以收獲如下益處:
減少代碼的數(shù)量:利用Python內(nèi)置函數(shù)或者列表推導式,可以更簡潔地執(zhí)行常見的操作,通常這可以在完成相同的任務(wù)時,用更少的代碼替代for循環(huán)。
增強代碼的可讀性:使用列表推導式或內(nèi)置函數(shù)的代碼,通常比使用等效的for循環(huán)的代碼更容易一看就明白。這是因為這些構(gòu)造抽象了循環(huán)機制,更關(guān)注正在執(zhí)行的操作。
減少縮進(這在Python里尤為重要):Python高度依賴于縮進來定義代碼塊的結(jié)構(gòu)。避免使用循環(huán)可以減少額外縮進級別的需求,使代碼更簡潔、更易于理解。這在Python 中特別有用,它強調(diào)可讀性和簡單性。
下面的例子中:
with open('example_file.txt', 'r') as file:
for line in file:
if 'keyword' in line:
try:
value = int(line.strip())
print(value)
except ValueError:
print("Conversion error occurred.")
else:
print("Keyword not found in line.")
在這個例子中,代碼有許多嵌套結(jié)構(gòu),因此可讀性會變得困難。這個例子展示了深度嵌套代碼的運用。
在此代碼片段中,通過不加選擇地將控制流結(jié)構(gòu)(如 with 和 try-except 塊)與業(yè)務(wù)邏輯(如 for循環(huán)和 if語句)混雜在一起,產(chǎn)生了過多的縮進。如果能夠堅持主要為控制流結(jié)構(gòu)保留縮進,核心業(yè)務(wù)邏輯應(yīng)該就會變得更加清晰,更易于理解。
列表推導及生成器
Python中的列表推導和生成器表達式為處理和操作諸如列表或可迭代對象的集合提供了緊湊的方式。
列表推導
列表推導是創(chuàng)建新列表的簡潔方式。包含一個表達式,然后是一個 for 子句,接著是零個或多個for或if子句,最后得到一個新的列表。這個表達式可以是任何物件,代表可以放入列表的任何類型。最后的結(jié)果是新列表,它由后面的 for和 if 子句的上下文中進行評估后產(chǎn)生。它通常比通過正常的函數(shù)和循環(huán)創(chuàng)建列表更緊湊、更快捷。
例如,[x**2 For x in range(10)]將輸出包含0到9的數(shù)字平方的列表。
生成器表達式
生成器表達式類似于列表推導,不過它們不是創(chuàng)建整個列表并一次性存儲所有的項目,而是逐個生成項目,然后丟棄。這意味著生成器表達式的內(nèi)存效率是優(yōu)于相應(yīng)的列表推導式的。
例如,(x**2 for x in range(10))創(chuàng)建一個生成器,它一次計算一個,對0至9的數(shù)字進行平方。
示例:
result = []
for item in item_list:
new_item = do_something_with(item)
result.append(item)
可改寫為:
result = [do_something_with(item) for item in item_list]
Map/Reduce函數(shù)
在Python中,map和reduce功能是把指定的函數(shù)應(yīng)用于可迭代序列(如列表),并分別將其縮小為一個累積值。
map 函數(shù)
map函數(shù)把特定的函數(shù)適用于可迭代對象(如列表)的每一項,并返回一個結(jié)果列表。語法是map(function, iterable, ...)。當你想對集合中的每一個項目執(zhí)行相同的操作而不需要編寫顯式循環(huán)時,此功能十分有用。
例如,.map(lambda x: x * 2, [1, 2, 3, 4])會返回[2, 4, 6, 8]
reduce 函數(shù)
reduce函數(shù)是functools模塊的一部分,它重復將給定函數(shù)應(yīng)用于序列元素,并以單一值形式返回它。傳遞給reduce的函數(shù)必須接受兩個參數(shù),這個函數(shù)從左到右地累積應(yīng)用于可迭代項目,以便將可迭代項目減少為單個值。
例如,reduce(lambda x, y: x+y, [1, 2, 3, 4])會把列表中的數(shù)加在一起并得到10。
map表述變換,reduce表述累加。兩者都是Python中函數(shù)式編程風格的示例,可以將函數(shù)應(yīng)用于序列和其他可迭代對象。
多函數(shù)使用
上述的方法非常適合處理簡單的邏輯。但對于更復雜的邏輯呢?作為程序員,我們編寫函數(shù)來簡化復雜的操作。同樣的概念也適用于這里。如果你的代碼像這樣:
results = []
for item in item_list:
# 建立
# 判斷
# 處理
# 計算
results.append(result)
很明顯,你為單個代碼塊分配了太多工作。相反,我建議你考慮下面的方法:
def process_item(item):
# 建立
# 判斷
# 處理
# 計算
return result
results = [process_item(item) for item in item_list]
有時,你可能需要使用嵌套函數(shù),比如這樣:
results = []
for i in range(10):
for j in range(i):
results.append((i, j))
它可以被改寫為:
results = [(i, j)
for i in range(10)
for j in range(i)]
有時,你的代碼需要保持一些內(nèi)部狀態(tài),例如:
my_list = [10, 4, 13, 2, 1, 9, 0, 7, 5, 8]
results = []
current_max = 0
for i in my_list:
current_max = max(i, current_max)
results.append(current_max)
這可以被重寫為:
from itertools import accumulate
my_list = [10, 4, 13, 2, 1, 9, 0, 7, 5, 8]
results = list(accumulate(my_list, max))
現(xiàn)在是不是已經(jīng)看起來更像Python了?此外,第二種方法,使用accumulate from itertools模塊,拿來做累積運算通常更有效率且更Pythonic,原因有以下幾點:
內(nèi)置函數(shù)效率:accumulate是Python中的內(nèi)置函數(shù),特地被優(yōu)化來執(zhí)行累積運算的任務(wù),基本上比手動實現(xiàn)的for循環(huán)來得快。
可讀性:accumulate函數(shù)清楚地傳達了用特定的操作(在本例中為max)累積值的意圖,使代碼更容易理解。
簡潔性:第二種辦法更簡潔,與第一種辦法的四行代碼相比,只需兩行就可完成任務(wù)。這就減少了出錯的可能性,也讓代碼更干凈。
擴展性和維護性: 使用accumulate及其它內(nèi)置函數(shù),代碼更容易維護,改變也更容易,比如:應(yīng)用除了max之外的其他操作。
總結(jié)
本文主要討論了不同的Python編程策略,包括優(yōu)化嵌套結(jié)構(gòu)代碼,列表推導式和生成器表達式的使用,map和reduce函數(shù)的應(yīng)用以及高效使用多函數(shù)并在適當?shù)牡胤绞褂脙?nèi)建庫。
- 嵌套結(jié)構(gòu)的優(yōu)化有助于提高代碼的可讀性和清晰度,讓控制流結(jié)構(gòu)更直觀,業(yè)務(wù)邏輯更易于理解。
- 列表推導和生成器表達式是處理列表和可迭代對象的強大工具,它們能夠使代碼更加緊湊、高效。
- map和reduce函數(shù)可用于將特定功能應(yīng)用于序列,進一步提高代碼的效率和可讀性。
- 熟練地使用函數(shù)可以簡化復雜的邏輯,使代碼更易于維護,也符合Python的簡易優(yōu)雅原則。
- 最后,使用Python自帶的功能,如內(nèi)置函數(shù)和模塊,可以提高代碼的效率和可讀性,讓代碼更“Python化?!?/li>
綜上,只要掌握各種編程策略和Python內(nèi)部功能,就可以優(yōu)化你的代碼,從而提高編程效率,使代碼更容易理解,維護和修改。