五個(gè) Python 錯(cuò)誤讓你看起來很弱
Python是一種非常容易學(xué)習(xí)的語言,它不強(qiáng)制你使用特定的約定。同時(shí),你也很容易陷入一些陷阱,讓你看起來像是一個(gè)初學(xué)者。為了避免看起來完全是個(gè)初學(xué)者,看看下面的技巧以及如何修復(fù)它們。

1. 不使用enumerate()
Python使得遍歷列表等事物變得超級(jí)簡(jiǎn)單。看看下面的例子:
vals = ['Python', 'is', 'fun!']
for val in vals:
print(val)
# Returns:
# Python
# is
# fun!但是,如果你需要引用每個(gè)項(xiàng)目的索引會(huì)發(fā)生什么?你可能遇到過甚至寫過下面這樣的代碼:
vals = ['Python', 'is', 'fun!']
for i in range(len(vals)):
print(i, vals[i])
# Returns:
# 0 Python
# 1 is
# 2 fun!雖然這有效,但并不十分優(yōu)雅!它也沒有立即清楚地表明你的代碼在做什么。這里就是enumerate()函數(shù)發(fā)揮作用的地方!讓我們看看它讓這個(gè)過程變得多么容易:
for idx, val in enumerate(vals):
print(idx, val)
# Returns:
# 0 Python
# 1 is
# 2 fun!作為一個(gè)專業(yè)提示,你甚至可以改變起始值。比如說,如果你想從1開始標(biāo)記項(xiàng)目。然后你可以簡(jiǎn)單地寫:
vals = ['Python', 'is', 'fun!']
for idx, val in enumerate(vals, start=1):
print(idx, val)
# Returns:
# 1 Python
# 2 is
# 3 fun!2. 不使用三元運(yùn)算符
當(dāng)你使用if-else語句來賦值時(shí),你正在為一個(gè)簡(jiǎn)單動(dòng)作使用大量的代碼行。看看下面的場(chǎng)景:
amount = 100
if amount > 50:
raise_amount = 20
else:
raise_amount = 10
print(raise_amount)
# Returns:
# 20在上面的例子中,我們創(chuàng)建了一個(gè)if-else語句來檢查某人銷售的數(shù)量是否超過50。如果是,那么他們將獲得20的加薪。否則,他們將獲得10的加薪。雖然我們的代碼很清晰,但并不十分簡(jiǎn)潔。我們可以通過使用三元賦值來大大簡(jiǎn)化這一點(diǎn):
amount = 100
raise_amount = 20 if amount > 50 else 10
print(raise_amount)
# Returns:
# 20這最適合非常簡(jiǎn)單的賦值。雖然你可以更復(fù)雜,但不要為了簡(jiǎn)潔而犧牲可讀性!
3. 不使用推導(dǎo)式
Python推導(dǎo)式可以快速創(chuàng)建列表、字典甚至生成器。它們提供了一種優(yōu)雅且易于閱讀的方式來輕松創(chuàng)建數(shù)據(jù)結(jié)構(gòu)。讓我們看看你會(huì)如何使用for循環(huán)來創(chuàng)建一個(gè)平方數(shù)列表的例子:
squares = []
for i in range(1, 6):
squares.append(i ** 2)
print(squares)
# Returns:
# [1, 4, 9, 16, 25]現(xiàn)在讓我們比較一下使用列表推導(dǎo)式的情況:
squares = [i ** 2 for i in range(1, 6)]
print(squares)
# Returns:
# [1, 4, 9, 16, 25]我們可以看到使用列表推導(dǎo)式是多么簡(jiǎn)單和明確!代碼不僅更簡(jiǎn)潔,而且更容易閱讀。創(chuàng)建字典推導(dǎo)式也同樣容易。讓我們?cè)俅伪容^兩種方法,創(chuàng)建一個(gè)字典,其中鍵是原始數(shù)字,值是它的平方:
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)在讓我們看看我們?nèi)绾问褂米值渫茖?dǎo)式來簡(jiǎn)化這個(gè)!
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)在,也很容易過度使用推導(dǎo)式,對(duì)一切都使用推導(dǎo)式。所以我會(huì)在這里加上一個(gè)額外的提示:除非有意義,否則不要對(duì)一切都使用它們!
4. 過度使用推導(dǎo)式
Python推導(dǎo)式非常強(qiáng)大——真的非常強(qiáng)大。你可以內(nèi)置復(fù)雜的if-else語句,甚至可以將它們嵌套在一起。讓我們看看我們?nèi)绾谓Y(jié)合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']在上面的例子中,我們使用三元運(yùn)算符在繼續(xù)迭代的同時(shí)返回一個(gè)值。現(xiàn)在,這個(gè)例子很簡(jiǎn)單——但讓我們看看一個(gè)更復(fù)雜的:
result = [x * 2 if x % 2 == 0 else x * 3 for x in range(10) if x != 5]這一點(diǎn)也不有趣,難以閱讀。這就引出了我的主要觀點(diǎn)——如果使用for循環(huán)更清晰,就不要寫推導(dǎo)式。讓我們將這個(gè)推導(dǎo)式轉(zhuǎ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)我們可以看到,雖然我們用更多的行來寫這段代碼,但它的可讀性要高得多!
5. 不使用itertools
Python的itertools是內(nèi)置在Python中的一個(gè)隱藏的寶石。表面上,它的許多功能看起來很簡(jiǎn)單,但它們提供了優(yōu)雅而強(qiáng)大的方法來迭代不同的對(duì)象。
防止嵌套循環(huán)
假設(shè)你有兩個(gè)列表,你想遍歷所有可能的組合。你可以像下面這樣編寫一個(gè)嵌套的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類似于我們?cè)谶@篇文章中討論的其他一切,這種方法有效,但并不十分優(yōu)雅。幸運(yùn)的是,itertools帶有product()函數(shù),它創(chuàng)建了所有項(xiàng)目的笛卡爾積。這意味著我們可以直接在一個(gè)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成對(duì)遍歷列表
在某些情況下,你需要成對(duì)地遍歷列表,這意味著你需要訪問一個(gè)項(xiàng)目及其鄰居。為此,你可以編寫以下代碼:
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()函數(shù)派上用場(chǎng)的地方!讓我們看看我們?nèi)绾魏?jiǎn)化我們的代碼:
from itertools import pairwise
vals = [1, 2, 3, 4]
for pair in pairwise(vals):
print(pair)
# Returns:
# (1, 2)
# (2, 3)
# (3, 4)這是一個(gè)比我們之前寫的代碼更明確的版本,讓我們立即理解代碼的目的。itertools庫(kù)為你提供了許多有用的函數(shù)來迭代對(duì)象。知道何時(shí)應(yīng)用這些函數(shù)真的能讓你的技能提升到另一個(gè)層次。
結(jié)論
掌握Python不僅僅是記住語法——它是關(guān)于擁抱優(yōu)雅,知道何時(shí)在簡(jiǎn)潔性和可讀性之間取得平衡。






























