溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

有哪些技巧編寫(xiě)出更好的Python代碼

發(fā)布時(shí)間:2021-10-29 11:37:34 來(lái)源:億速云 閱讀:171 作者:iii 欄目:編程語(yǔ)言

這篇文章主要講解了“有哪些技巧編寫(xiě)出更好的Python代碼”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“有哪些技巧編寫(xiě)出更好的Python代碼”吧!

1. 使用enumerate()而不是range(len())進(jìn)行迭代

如果我們需要遍歷一個(gè)列表,并且需要跟蹤索引和當(dāng)前項(xiàng),大多數(shù)人會(huì)使用range(len())語(yǔ)法。在本例中,我們希望遍歷一個(gè)列表,檢查當(dāng)前項(xiàng)是否為負(fù),并在本例中將列表中的值設(shè)置為0。雖然range(len())語(yǔ)法可以工作,但使用內(nèi)置的枚舉函數(shù)更好。這將以元組的形式返回當(dāng)前索引和當(dāng)前項(xiàng)。因此,我們可以直接檢查這里的值,也可以訪問(wèn)帶有索引的項(xiàng)。

data = [1, 2, -3, -4] # weak: for i in range(len(data)):     if data[i] < 0:         data[i] = 0  # better: data = [1, 2, -3, -4] for idx, num in enumerate(data):     if num < 0:         data[idx] = 0

2. 使用list comprehension代替原始的for循環(huán)

假設(shè)我們想要?jiǎng)?chuàng)建一個(gè)具有特定值的列表,在本例中是一個(gè)包含0到9之間所有平方數(shù)的列表。冗長(zhǎng)乏味的方法是創(chuàng)建一個(gè)空列表,然后使用for循環(huán),進(jìn)行計(jì)算,并將其附加到列表中:

squares = [] for i in range(10):     squares.append(i*i)

一種更簡(jiǎn)單的方法是list comprehension。這里我們只需要一行來(lái)實(shí)現(xiàn)同樣的事情:

# better: squares = [i*i for i in range(10)]

list comprehension能力非常強(qiáng)大,甚至包括if語(yǔ)句。注意,list  comprehension的用法有一點(diǎn)爭(zhēng)議。它不應(yīng)該被過(guò)度使用,尤其是當(dāng)它損害了代碼的可讀性時(shí)。但我個(gè)人認(rèn)為這種語(yǔ)法是清晰和簡(jiǎn)潔的。

3. 使用內(nèi)置的Sort()方法對(duì)復(fù)雜的迭代進(jìn)行排序

如果我們需要對(duì)一些可迭代的對(duì)象,例如列表、元組或字典進(jìn)行排序,我們不需要自己實(shí)現(xiàn)排序算法。我們可以簡(jiǎn)單地使用內(nèi)置的排序函數(shù)。這將自動(dòng)按升序?qū)?shù)字進(jìn)行排序,并返回一個(gè)新的列表。如果我們想讓結(jié)果按降序排列,我們可以使用參數(shù)reverse=True。正如我所說(shuō)的,這適用于任何可迭代的對(duì)象,所以這里我們還可以使用元組。但是請(qǐng)注意,結(jié)果是一個(gè)列表!

data = (3, 5, 1, 10, 9) sortedsorted_data = sorted(data, reverse=True) # [10, 9, 5, 3, 1]

現(xiàn)在假設(shè)我們有一個(gè)復(fù)雜的迭代器。這里是一個(gè)列表,列表里面有字典,我們想要根據(jù)字典中的年齡對(duì)列表進(jìn)行排序。為此,我們還可以使用排序函數(shù),然后傳入應(yīng)該用于排序的關(guān)鍵參數(shù)。鍵必須是一個(gè)函數(shù),所以這里我們可以使用lambda和返回年齡的單行函數(shù)。

data = [{"name": "Max", "age": 6},          {"name": "Lisa", "age": 20},          {"name": "Ben", "age": 9}         ] sortedsorted_data = sorted(data, key=lambda x: x["age"])

4. 用集合存儲(chǔ)惟一的值

如果我們有一個(gè)有多個(gè)值的列表,并且只需要唯一的值,一個(gè)很好的技巧是將我們的列表轉(zhuǎn)換為集合。集合是一種無(wú)序的集合數(shù)據(jù)類型,沒(méi)有重復(fù)的元素,所以在這種情況下,它刪除了所有重復(fù)的元素。

my_list = [1,2,3,4,5,6,7,7,7] my_set = set(my_list) # removes duplicates

如果我們已經(jīng)知道我們需要唯一的元素,比如這里的質(zhì)數(shù),我們可以馬上用花括號(hào)創(chuàng)建一個(gè)集合。這允許Python進(jìn)行一些內(nèi)部?jī)?yōu)化,并且它還有一些方便的方法來(lái)計(jì)算兩個(gè)集合之間的交集和差異。

5. generator節(jié)省內(nèi)存

在技巧2中,我向你展示了list  comprehension。但是列表并不總是最好的選擇。假設(shè)我們有一個(gè)非常大的列表有10000項(xiàng)我們想計(jì)算所有項(xiàng)的和。當(dāng)然,我們可以使用列表來(lái)實(shí)現(xiàn)這一點(diǎn),但是我們可能會(huì)遇到內(nèi)存問(wèn)題。這是一個(gè)我們可以使用生成器的完美例子。與list  comprehension類似,我們可以使用生成器理解,它具有相同的語(yǔ)法,但使用圓括號(hào)而不是方括號(hào)。生成器懶洋洋地計(jì)算我們的元素,即。,它一次只生成一個(gè)條目,并且只在被請(qǐng)求時(shí)生成。如果我們計(jì)算這個(gè)生成器的和,我們看到我們得到了相同的正確結(jié)果。

# list comprehension my_list = [i for i in range(10000)] print(sum(my_list)) # 49995000  # generator comprehension my_gen = (i for i in range(10000)) print(sum(my_gen)) # 49995000

6. 用.get()和.setdefault()在字典中定義默認(rèn)值

假設(shè)我們有一個(gè)字典,它有不同的鍵,比如物品和物品的價(jià)格。在代碼的某個(gè)時(shí)候,我們想要獲得條目的計(jì)數(shù),并且假設(shè)這個(gè)鍵也包含在字典中。當(dāng)我們簡(jiǎn)單地嘗試訪問(wèn)密鑰時(shí),它將崩潰我們的代碼并引發(fā)一個(gè)KeyError。所以更好的方法是在字典上使用.get()方法。這也會(huì)返回鍵的值,但是如果鍵不可用,它不會(huì)引發(fā)鍵錯(cuò)誤。相反,它返回我們指定的默認(rèn)值,如果我們沒(méi)有指定它,則返回None。

my_dict = {'item': 'football', 'price': 10.00} price = my_dict['count'] # KeyError!  # better: price = my_dict.get('count', 0) # optional default value

7. 用collections.Counter計(jì)數(shù)hashable對(duì)象

如果我們需要計(jì)算列表中元素的數(shù)量,那么在collections模塊中有一個(gè)非常方便的工具可以完成此工作。我們只需要從集合中導(dǎo)入計(jì)數(shù)器,然后用列表作為參數(shù)創(chuàng)建計(jì)數(shù)器對(duì)象。如果我們打印這個(gè),那么對(duì)于列表中的每一項(xiàng),我們都可以看到這個(gè)項(xiàng)出現(xiàn)的次數(shù),而且它已經(jīng)排好序了,最常用的項(xiàng)在前面。單獨(dú)計(jì)算會(huì)好得多。如果我們想要獲得某一項(xiàng)的計(jì)數(shù),只需訪問(wèn)該項(xiàng),它就會(huì)返回相應(yīng)的計(jì)數(shù)。如果不包含該項(xiàng),則返回0。

from collections import Counter  my_list = [10, 10, 10, 5, 5, 2, 9, 9, 9, 9, 9, 9] counter = Counter(my_list)  print(counter) # Counter({9: 6, 10: 3, 5: 2, 2: 1}) print(counter[10]) # 3

8. 用f-strings格式化字符串(Python 3.6+)

這是自Python  3.6以來(lái)的新特性,在我看來(lái)是格式化字符串的最佳方式。我們只需要在字符串前面寫(xiě)一個(gè)f,然后在字符串里面我們可以使用大括號(hào)來(lái)訪問(wèn)變量。與舊的格式化規(guī)則相比,這更簡(jiǎn)單、更簡(jiǎn)潔,也更快。此外,我們可以在大括號(hào)中編寫(xiě)在運(yùn)行時(shí)計(jì)算的表達(dá)式。舉個(gè)例子,我們想要輸出變量i的平方,我們可以簡(jiǎn)單地把這個(gè)操作寫(xiě)在f字符串中。

name = "Alex" my_string = f"Hello {name}" print(my_string) # Hello Alex  i = 10 print(f"{i} squared is {i*i}") # 10 squared is 100

9. 用.join()連接字符串

假設(shè)我們有一個(gè)包含不同字符串的列表,我們想將所有元素組合成一個(gè)字符串,每個(gè)單詞之間用空格分隔。壞的方法是這樣做:

list_of_strings = ["Hello", "my", "friend"]  # BAD: my_string = "" for i in list_of_strings:     my_string += i + " "

我們定義了一個(gè)空字符串,然后遍歷該列表,然后將單詞和空格追加到該字符串。你應(yīng)該知道,字符串是不可變的元素,所以這里我們每次都要?jiǎng)?chuàng)建新的字符串。對(duì)于大型列表,此代碼可能非常慢,所以您應(yīng)該立即忘記這種方法!更好、更快、也更簡(jiǎn)潔的是.join()方法:

.join() method: # GOOD: list_of_strings = ["Hello", "my", "friend"] my_string = " ".join(list_of_strings)

10. 用雙星號(hào)語(yǔ)法合并字典** (Python 3.5+)

這種語(yǔ)法是自Python  3.5以來(lái)的新語(yǔ)法。如果我們有兩個(gè)字典并且想要合并它們,我們可以為兩個(gè)字典使用花括號(hào)和雙星號(hào)。這里字典1有名字和年齡,字典2也有名字和城市。在與這個(gè)簡(jiǎn)潔的語(yǔ)法合并之后,我們最終的字典中有所有3個(gè)鍵。

d1 = {'name': 'Alex', 'age': 25} d2 = {'name': 'Alex', 'city': 'New York'} merged_dict = {**d1, **d2} print(merged_dict) # {'name': 'Alex', 'age': 25, 'city': 'New York'}

11. 用if x in list簡(jiǎn)化if語(yǔ)句,而不是單獨(dú)檢查每一項(xiàng)

假設(shè)我們有一個(gè)主色為紅色、綠色和藍(lán)色的列表。在代碼的某個(gè)地方,我們有一個(gè)包含一些顏色的新變量,這里是c  =紅色。然后我們要檢查這個(gè)顏色是否來(lái)自我們的主色。我們當(dāng)然可以像這樣檢查列表中的每一項(xiàng):

colors = ["red", "green", "blue"]  c = "red"  # cumbersome and error-prone if c == "red" or c == "green" or c == "blue":     print("is main color")

但這可能會(huì)變得很麻煩,我們很容易出錯(cuò),例如,如果我們這里有一個(gè)錯(cuò)誤的紅色。更簡(jiǎn)單也更好的方法是使用語(yǔ)法if x in list。

感謝各位的閱讀,以上就是“有哪些技巧編寫(xiě)出更好的Python代碼”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)有哪些技巧編寫(xiě)出更好的Python代碼這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI