四個Python初學者式的錯誤及其優(yōu)化建議
Python是一種非常容易學習的語言,而且它不會強迫你使用特定的慣例。但它也很容易陷入一些誤區(qū),讓你看起來像個初學者。為了避免看起來像個完全的初學者,請查看下面的提示以及如何解決這些問題。
1. 不使用enumerate()
Python使得遍歷諸如列表之類的事物變得非常容易。讓我們看看下面的示例:
vals = ['Python', 'is', 'fun!']
for val in vals:
print(val)
# Returns:
# Python
# is
# fun!
但是,如果你需要引用每個項目的索引,該怎么辦呢?你可能已經遇到或者甚至編寫了類似下圖所示的代碼:
vals = ['Python', 'is', 'fun!']
for i in range(len(vals)):
print(i, vals[i])
# Returns:
# 0 Python
# 1 is
# 2 fun!
這種方法雖然可行,但它并不優(yōu)雅。它也不能立即清楚地說明你的代碼在做什么。
這就是enumerate()函數的用武之地!讓我們看看它如何使這個過程變得更加簡單:
vals = ['Python', 'is', 'fun!']
for idx, val in enumerate(vals):
print(idx, val)
# Returns:
# 0 Python
# 1 is
# 2 fun!
作為一個專業(yè)提示,你甚至可以改變起始值。比如說,你想從1開始標記項目,那么你可以這樣簡單地寫:
vals = ['Python', 'is', 'fun!']
for idx, val in enumerate(vals, start=1):
print(idx, val)
# Returns:
# 1 Python
# 2 is
# 3 fun!
2. 不使用三元運算符
當你使用if-else語句來分配值時,你需要編寫很多行代碼來完成一個簡單的操作。請看下面的場景:
amount = 100
if amount > 50:
raise_amount = 20
else:
raise_amount = 10
print(raise_amount)
# Returns:
# 20
在上面的例子中,我們創(chuàng)建了一個if-else語句,檢查某人的銷售金額是否超過50。如果是,那么他們就獲得20的漲幅。否則,他們獲得10的漲幅。
雖然我們的代碼很干凈,但并不簡潔。我們可以通過使用三元賦值來大大簡化它:
amount = 100
raise_amount = 20 if amount > 50 else 10
print(raise_amount)
# Returns:
# 20
這種方法最適用于非常簡單的作業(yè)。雖然可以做得更復雜,但不要為了簡潔而犧牲可讀性。
3. 使用推導式
3.1 不使用推導式
Python推導式使創(chuàng)建列表、字典和生成器變得輕而易舉。它們提供了一種優(yōu)雅且易讀的方式來輕松創(chuàng)建數據結構。
讓我們看一個例子,看看如何使用for循環(huán)來創(chuàng)建一個平方數列表:
squares = []
for i in range(1, 6):
squares.append(i ** 2)
print(squares)
# Returns:
# [1, 4, 9, 16, 25]
現(xiàn)在,讓我們將其與列表推導式進行比較:
squares = [i ** 2 for i in range(1, 6)]
print(squares)
# Returns:
# [1, 4, 9, 16, 25]
我們可以看到使用列表推導式要簡單和明確得多!代碼不僅更簡潔,而且也更容易閱讀。
創(chuàng)建字典推導式也同樣簡單。讓我們再次比較這兩種方法,創(chuàng)建一個字典,其中鍵是原始數字,值是它的平方:
squares = {}
for i in range(1, 6):
squares[i] = i ** 2
print(squares)
# Returns:
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
現(xiàn)在,讓我們看看如何通過字典推導式來簡化這一過程。
squares = {i: i**2 for i in range(1, 6)}
print(squares)
# Returns:
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
現(xiàn)在,過度使用推導式也是一個問題。所以在這里有一個額外的提示:除非有必要,否則不要什么都用它們。
3.2 過度使用推導式
Python推導式非常強大。你可以內置復雜的if-else語句,甚至可以將它們嵌套在彼此之中。
讓我們看看如何加入if-else語句:
even_odd_numbers = [
"Even" if num % 2 == 0 else "Odd"
for num in range(10)
]
print(even_odd_numbers)
# Returns:
# ['Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd', 'Even', 'Odd']
在上面的例子中,我們使用三元運算符在繼續(xù)迭代的同時返回一個值?,F(xiàn)在,這個例子相當簡單,但讓我們看一個更復雜的例子:
result = [x * 2 if x % 2 == 0 else x * 3 for x in range(10) if x != 5]
這絕對不是什么有趣、可讀的東西。這就引出了這里的重點——如果推導式比使用for循環(huán)更不清晰,那就不要寫推導式。
讓我們將這個推導式轉換為一個循環(huán),看看它變得有多易讀:
result = []
for x in range(10):
if x != 5:
if x % 2 == 0:
result.append(x * 2)
else:
result.append(x * 3)
可以看到,雖然我們用了更多行來編寫這段代碼,但它的可讀性卻大大提高了。
4. 不使用itertools
Python的itertools是內置于Python中的一個函數庫。雖然表面上看,它的許多函數似乎很簡單,但它們提供了優(yōu)雅而強大的方式來遍歷不同的對象。
4.1 避免嵌套循環(huán)
假設你有兩個列表,你想遍歷所有可能的組合。可以編寫如下所示的嵌套for循環(huán):
colors = ['Red', 'Green']
sizes = ['S', 'M', 'L']
for color in colors:
for size in sizes:
print(color, size)
# Returns:
# Red S
# Red M
# Red L
# Green S
# Green M
# Green L
與我們在本文中介紹的其他方法類似,這種方法雖然有效,但并不優(yōu)雅。
值得慶幸的是,itertools提供了product()函數,它可以創(chuàng)建所有項目的笛卡爾積。這意味著我們可以在一個for循環(huán)中直接解包這些值,代碼如下所示:
from itertools import product
colors = ['Red', 'Green']
sizes = ['S', 'M', 'L']
for color, size in product(colors, sizes):
print(color, size)
# Returns:
# Red S
# Red M
# Red L
# Green S
# Green M
# Green L
可以看到這種方法簡單多了。
4.2 成對遍歷列表
在某些情況下,你需要成對地遍歷列表,這意味著你需要訪問一個項目及其相鄰的項目。
要做到這一點,可以編寫以下代碼:
vals = [1, 2, 3, 4]
for i in range(len(vals) - 1):
print((vals[i], vals[i+1]))
# Returns:
# (1, 2)
# (2, 3)
# (3, 4)
這種方法效果很好,但可讀性不強,其作用也不是很明確。
這就是Python 3.10引入的pairwise()函數的用武之地。讓我們看看如何簡化代碼:
from itertools import pairwise
vals = [1, 2, 3, 4]
for pair in pairwise(vals):
print(pair)
# Returns:
# (1, 2)
# (2, 3)
# (3, 4)
這是我們之前編寫的代碼的一個更加明確的版本,使我們能夠立即了解代碼的目的。
itertools庫為用戶提供了許多有用的對象迭代函數。知道何時應用這些函數可以將你的技能提升到更高的層次。
結論
掌握Python不僅僅是記住語法,更重要的是擁抱優(yōu)雅,并知道何時在簡潔和可讀性之間取得平衡。
牢記Python之禪:
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
上述提示應能真正幫助你領悟Python之禪的這一開始的幾行。