優化重構Python程式碼6個小建議

www88xbocom【17176934555】發表於2021-04-06
  1. 合併巢狀的 if 條件

太多的巢狀會使程式碼難以理解,這在 Python 中尤為如此,因為 Python 沒有括號來幫助區隔不同的巢狀級別。

閱讀深度巢狀的程式碼容易讓人煩躁,因為你必須理清哪些條件屬於哪一級。因此,我們應儘可能減少巢狀,如果兩個條件可以用 and 合在一起,會比巢狀更易讀。

合併之前:

if a:
if b:
return c

合併後:

if a and b:
return c

  1. 將重複的程式碼移到條件語句之外

我們應該始終尋找移除重複程式碼的方法。這是提升程式碼能力的好辦法。

有時,在條件的兩個分支上出現重複程式碼,這意味這段程式碼將始終執行。因此這段重複的程式碼可以從條件中移出,放在條件之外執行。

if sold > DISCOUNT_AMOUNT:
total = sold * DISCOUNT_PRICE
label = f’Total: {total}’
else:
total = sold * PRICE
label = f’Total: {total}’

通過將對label變數賦值移到到條件之外,我們刪除了重複的程式碼行,並明確了條件實際控制的內容,就是計算total。

if sold > DISCOUNT_AMOUNT:
total = sold * DISCOUNT_PRICE
else:
total = sold * PRICE
label = f’Total: {total}’

  1. 將內部迴圈中的 yield 替換為 yield from

經常忽略的一個小竅門是 Python 的yield關鍵字有對應的為collections準備的yield from。因此無需使用 for 迴圈遍歷集合。這使程式碼變短,並刪除 for 中的額外變數。而且消除 for 迴圈後,yield from使程式執行效率提高約 15%。

重構前:

def get_content(entry):
for block in entry.get_blocks():
yield block

重構後:

def get_content(entry):
yield from entry.get_blocks()

  1. 使用 any() 而不是用於迴圈

常見的模式是,我們需要查詢是否集合中的一個或多個項符合某些條件。這可以通過 for 迴圈完成,例如:

found = False
for thing in things:
if thing == other_thing:
found = True
break

更簡潔的方法,是使用 Python 的 any() 和 all() 內建函式,來清楚地顯示程式碼的意圖。

found = any(thing == other_thing for thing in things)

當至少有一個元素計算為 True 時,any() 將返回 True,只有當所有元素都計算為 True 時,all() 將返回 True。

如果對 any() 的呼叫找到一個值為 True 的元素,它可以立即返回。

  1. 用 [ ] 替換 list()

建立列表的最簡潔和 Pythonic 的方法是使用 []。

x = []
x = [‘first’, ‘second’]

這樣做有額外的優點:是一個很好的改程式序效能的方法。

以下是更改之前和之後的時間對比:

$ python3 -m timeit “x = list()”
5000000 loops, best of 5: 63.3 nsec per loop

$ python3 -m timeit “x = []”
20000000 loops, best of 5: 15.8 nsec per loop

同樣的原因和效能表現,使用 { } 替代 dict()。

  1. 將重複執行的語句移出 for / while 迴圈

將“不變的”語句從迴圈中移出。如果某條語句只是設定了一些變數供迴圈使用,則不需要在迴圈中。迴圈本身就是複雜的,因此在編寫迴圈時,應牢記,使其更短、更容易理解。

在此示例中,city變數在迴圈中賦值,但它只讀取且不更改。

for building in buildings:
city = ‘London’
addresses.append(building.street_address, city)

因此,將其移出是安全的,這更清楚地說明,相同的city值將應用於每個building變數。

city = ‘London’
for building in buildings:
addresses.append(building.street_address, city)

這也是提高了程式效能 ,因為如果迴圈中的任何語句將在每次迴圈執行時執行。在這些多次執行上花費的時間屬於浪費,因為它只需要執行一次。如果語句涉及對資料庫的呼叫或其他耗時的任務,則這種節省可能非常重要。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章