4.1 遍歷整個(gè)列表
我們我們經(jīng)常需要遍歷列表的所有元素,對每個(gè)元素執(zhí)行相同的操作。這時(shí)需要對列表中的每個(gè)元素都執(zhí)行相同的操作時(shí),可使用Python中的for 循環(huán)。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
alice
david
carolina
4.1.1 深入地研究循環(huán)
循環(huán)這種概念很重要,因?yàn)樗亲層?jì)算機(jī)自動完成重復(fù)工作的常見方式之一。
使用循環(huán)時(shí)請牢記,對列表中的每個(gè)元素,都將執(zhí)行循環(huán)指定的步驟,而不管列表包含多少個(gè)元素。如果列表包含一百萬個(gè)元素,Python就重復(fù)執(zhí)行指定的步驟一百萬次,且通常速度非常快。
對于用于存儲列表中每個(gè)值的臨時(shí)變量,可指定任何名稱。然而,選擇描述單個(gè)列表元素的有意義的名稱大有幫助。例如,對于小貓列表、小狗列表和一般性列表,像下面這樣編寫for循環(huán)的第一行代碼是不錯的選擇:
for cat in cats:
for dog in dogs:
for item in list_of_items:
這些命名約定有助于你明白for 循環(huán)中將對每個(gè)元素執(zhí)行的操作。使用單數(shù)和復(fù)數(shù)式名稱,可幫助你判斷代碼段處理的是單個(gè)列表元素還是整個(gè)列表。
4.1.2 在for循環(huán)中執(zhí)行更多的操作
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!
在for循環(huán)中,想包含多少行代碼都可以。在代碼行for magician in magicians后面,每個(gè)縮進(jìn)代碼行都是循環(huán)的一部分,且將針對列表中的每個(gè)值都執(zhí)行一次。因此,可對列表中的每個(gè)值執(zhí)行任意次數(shù)的操作。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, {} n".format(magician.title()))
Alice, that was a great trick!
I can't wait to see your next trick, Alice
David, that was a great trick!
I can't wait to see your next trick, David
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina
4.1.3 在for 循環(huán)結(jié)束后執(zhí)行一些操作
在for循環(huán)后面,沒有縮進(jìn)的代碼都只執(zhí)行一次,而不會重復(fù)執(zhí)行。
使用for 循環(huán)處理數(shù)據(jù)是一種對數(shù)據(jù)集執(zhí)行整體操作的不錯的方式。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, " + magician.title() + ".n")
print("Thank you, everyone. That was a great magic show!")
Alice, that was a great trick!
I can't wait to see your next trick, Alice.
David, that was a great trick!
I can't wait to see your next trick, David.
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.
Thank you, everyone. That was a great magic show!
4.2 避免縮進(jìn)錯誤
Python根據(jù)縮進(jìn)來判斷代碼行與前一個(gè)代碼行的關(guān)系,通過使用縮進(jìn)讓代碼更易讀;簡單地說,它要求你使用縮進(jìn)讓代碼整潔而結(jié)構(gòu)清晰。在較長的Python程序中,你將看到縮進(jìn)程度各不相同的代碼塊,這讓你對程序的組織結(jié)構(gòu)有大致的認(rèn)識。
當(dāng)你開始編寫必須正確縮進(jìn)的代碼時(shí),需要注意一些常見的縮進(jìn)錯誤。
4.2.1 忘記縮進(jìn)
對于位于for 語句后面且屬于循環(huán)組成部分的代碼行,一定要縮進(jìn)。如果你忘記縮進(jìn),Python會提醒你應(yīng)縮進(jìn)卻沒有縮進(jìn)。Python沒有找到期望縮進(jìn)的代碼塊時(shí),會讓你知道哪行代碼有問題。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
File "< ipython-input-5-bc3e0c643e2b >", line 3
print(magician)
^
IndentationError: expected an indented block
4.2.2 忘記縮進(jìn)額外的代碼行
有時(shí)候,循環(huán)能夠運(yùn)行而不會報(bào)告錯誤,但結(jié)果可能會出乎意料。試圖在循環(huán)中執(zhí)行多項(xiàng)任務(wù),卻忘記縮進(jìn)其中的一些代碼行時(shí),就會出現(xiàn)這種情況。
這時(shí)產(chǎn)生的是邏輯錯誤 。從語法上看,這些Python代碼是合法的,但由于存在邏輯錯誤,結(jié)果并不符合預(yù)期。如果預(yù)期某項(xiàng)操作將針對每個(gè)列表元素都執(zhí)行一次,但它卻只執(zhí)行了一次,請確定是否需要將一行或多行代碼縮進(jìn)。
#注意循環(huán)中縮進(jìn)的影響
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, {}n".format(magician.title()))
Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina
4.2.3 不必要的縮進(jìn)
如果你不小心縮進(jìn)了無需縮進(jìn)的代碼行,Python將指出無需縮進(jìn),因?yàn)樗⒉粚儆谇耙恍写a。
message = "Hello Python world!"
print(message)
File "< ipython-input-7-e744c47c5d20 >", line 2
print(message)
^
IndentationError: unexpected indent
4.2.4 循環(huán)后不必要的縮進(jìn)
如果你縮進(jìn)了應(yīng)在循環(huán)結(jié)束后執(zhí)行的代碼,這些代碼將針對每個(gè)列表元素重復(fù)執(zhí)行。在有些情況下,這可能導(dǎo)致Python報(bào)告語法錯誤,但在大多數(shù)情況下,這只會導(dǎo)致邏輯錯誤。
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician.title() + ", that was a great trick!")
print("I can't wait to see your next trick, " + magician.title() + ".n")
#增加了不必要的縮進(jìn)
print("Thank you everyone, that was a great magic show!")
Alice, that was a great trick!
I can't wait to see your next trick, Alice.
Thank you everyone, that was a great magic show!
David, that was a great trick!
I can't wait to see your next trick, David.
Thank you everyone, that was a great magic show!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.
Thank you everyone, that was a great magic show!
4.2.5 遺漏了冒號
for 語句末尾的冒號告訴Python,下一行是循環(huán)的第一行。如果遺漏了冒號,將導(dǎo)致語法錯誤,因?yàn)镻ython不知道你意欲何為。
magicians = ['alice', 'david', 'carolina']
for magician in magicians
print(magician)
File "< ipython-input-9-0b84a6ab73bd >", line 2
for magician in magicians
^
SyntaxError: invalid syntax
練習(xí): 4-1 比薩 :想出至少三種你喜歡的比薩,將其名稱存儲在一個(gè)列表中,再使用for 循環(huán)將每種比薩的名稱都打印出來。
修改這個(gè)for 循環(huán),使其打印包含比薩名稱的句子,而不僅僅是比薩的名稱。對于每種比薩,都顯示一行輸出,如“I like pepperoni pizza”。
在程序末尾添加一行代碼,它不在for 循環(huán)中,指出你有多喜歡比薩。輸出應(yīng)包含針對每種比薩的消息,還有一個(gè)總結(jié)性句子,如“I really love pizza!”。
4-2 動物 :想出至少三種有共同特征的動物,將這些動物的名稱存儲在一個(gè)列表中,再使用for 循環(huán)將每種動物的名稱都打印出來。
修改這個(gè)程序,使其針對每種動物都打印一個(gè)句子,如“A dog would make a great pet”。
在程序末尾添加一行代碼,指出這些動物的共同之處,如打印諸如“Any of these animals would make a great pet!”這樣的句子。
# 4-1 不知道有些什么口味的pizza,亂來
print("----------------------")
pizzas = ['pepperoni', 'chicken', 'pork']
for pizza in pizzas:
print("I like {} pizza.".format(pizza))
print("I really love pizza!")
# 4-2
print("-----------------------")
pets = ['dog', 'cat', 'lizard']
for pet in pets:
print("A {} would make a great pet.".format(pet))
print("Any of these animals would make a great pet!")
----------------------
I like pepperoni pizza.
I like chicken pizza.
I like pork pizza.
I really love pizza!
-----------------------
A dog would make a great pet.
A cat would make a great pet.
A lizard would make a great pet.
Any of these animals would make a great pet!
4.3 創(chuàng)建數(shù)值列表
列表非常適合用于存儲數(shù)字集合,而Python提供了很多工具
4.3.1 使用函數(shù)range()
下例中range()只是打印數(shù)字1~4,這是經(jīng)常看到的差一行為的結(jié)果。如果要打印出1~5,我更喜歡下面的方式。
for value in range(1,5):
print(value)
1
2
3
4
for value in range(5):
print(value+1)
1
2
3
4
5
4.3.2 使用range() 創(chuàng)建數(shù)字列表
要創(chuàng)建數(shù)字列表,可使用函數(shù)list()將range() 的結(jié)果直接轉(zhuǎn)換為列表。如果將range()作為list()的參數(shù),輸出將為一個(gè)數(shù)字列表。
使用函數(shù)range() 時(shí),還可指定步長。第二段代碼打印1~10內(nèi)的偶數(shù)。
numbers = list(range(1,6))
print(numbers)
[1, 2, 3, 4, 5]
even_numbers = list(range(2,11,2))
print(even_numbers)
[2, 4, 6, 8, 10]
使用函數(shù)range() 幾乎能夠創(chuàng)建任何需要的數(shù)字集,例如,創(chuàng)建一個(gè)列表,其中包含前10個(gè)整數(shù)(即1~10)的平方:
squares=[]
for value in range(1,11):
square = value**2
squares.append(square)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#更簡潔的一種方法
squares = []
for value in range(1,11):
squares.append(value**2)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
創(chuàng)建更復(fù)雜的列表時(shí),可使用上述兩種方法中的任何一種。有時(shí)候,使用臨時(shí)變量會讓代碼更易讀;而在其他情況下,這樣做只會讓代碼無謂地變長。
首先應(yīng)該考慮的是,編寫清晰易懂且能完成所需功能的代碼;等到審核代碼時(shí),再考慮采用更高效的方法。
回想一下之前的python之禪(zen of python)。
4.3.3 對數(shù)字列表執(zhí)行簡單的統(tǒng)計(jì)計(jì)算
有幾個(gè)專門用于處理數(shù)字列表的Python函數(shù)。例如,找出數(shù)字列表的最大值、最小值和總和。
#更復(fù)雜、專業(yè)的統(tǒng)計(jì)可以通過numpy和pandas庫來實(shí)現(xiàn)。
digits = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(min(digits))
print(max(digits))
print(sum(digits))
0
9
45
4.3.4 列表解析
使用列表解析創(chuàng)建你在前面看到的平方數(shù)列表。使用這種語法,首先指定一個(gè)描述性的列表名,如squares;然后,指定一個(gè)左方括號,并定義一個(gè)表達(dá)式,用于生成你要存儲到列表中的值。在這個(gè)示例中,表達(dá)式為 ,它計(jì)算平方值。接下來,編寫一個(gè)for循環(huán),用于給表達(dá)式提供值,再加上右方括號。在這個(gè)示例中,for 循環(huán)為for value in range(1,11) ,它將值1~10提供給表達(dá)式。
這里的for 語句末尾沒有冒號。
squares = [value**2for value in range(1,11)]
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
練習(xí): 4-3 數(shù)到20 :使用一個(gè)for 循環(huán)打印數(shù)字1~20(含)。
4-4 一百萬 :創(chuàng)建一個(gè)列表,其中包含數(shù)字1~1 000 000,再使用一個(gè)for 循環(huán)將這些數(shù)字打印出來(如果輸出的時(shí)間太長,按Ctrl + C停止輸出,或關(guān)閉輸出窗口)。
4-5 計(jì)算11 000 000的總和 :創(chuàng)建一個(gè)列表,其中包含數(shù)字11 000 000,再使用min() 和max() 核實(shí)該列表確實(shí)是從1開始,到1 000 000結(jié)束的。另外,對這個(gè)列表調(diào)用函數(shù)sum() ,看看Python將一百萬個(gè)數(shù)字相加需要多長時(shí)間。
4-6 奇數(shù) :通過給函數(shù)range() 指定第三個(gè)參數(shù)來創(chuàng)建一個(gè)列表,其中包含1~20的奇數(shù);再使用一個(gè)for 循環(huán)將這些數(shù)字都打印出來。
4-7 3的倍數(shù) :創(chuàng)建一個(gè)列表,其中包含3~30內(nèi)能被3整除的數(shù)字;再使用一個(gè)for 循環(huán)將這個(gè)列表中的數(shù)字都打印出來。
4-8 立方 :將同一個(gè)數(shù)字乘三次稱為立方。例如,在Python中,2的立方用 表示。請創(chuàng)建一個(gè)列表,其中包含前10個(gè)整數(shù)(即1~10)的立方,再使用一個(gè)for 循環(huán)將這些立方數(shù)都打印出來。
4-9 立方解析 :使用列表解析生成一個(gè)列表,其中包含前10個(gè)整數(shù)的立方。
%time
# 4-3
print("-----4-3-----")
for value in range(1,21):
print(value,end='t')
print("n")
# 4-4
print("-----4-4-----")
values = list(range(1,101))
for value in values:
print(value,end='t')
print("n")
# 4-5
print("-----4-5-----")
values = list(range(1,1000001))
print(min(values),max(values))
print(sum(values))
# 4-6
print("-----4-6-----")
for odd in range(1,21,2):
print(odd,end='t')
print("n")
# 4-7
print("-----4-7-----")
for value in range(3,31,3):
print(value,end='t')
print("n")
# 4-8
print("-----4-8-----")
cubics = [value**3for value in range(1,11)]
for cubic in cubics:
print(cubic,end='t')
print("n")
# 4-9
print("-----4-9-----")
cubics = [value**3for value in range(1,11)]
print(cubics)
CPU times: user 7 μs, sys: 1 μs, total: 8 μs
Wall time: 15 μs
-----4-3-----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
-----4-4-----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
-----4-5-----
1 1000000
500000500000
-----4-6-----
1 3 5 7 9 11 13 15 17 19
-----4-7-----
3 6 9 12 15 18 21 24 27 30
-----4-8-----
1 8 27 64 125 216 343 512 729 1000
-----4-9-----
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
4.4 使用列表的一部分
除了處理列表的所有元素,還可以處理列表的部分元素——Python稱之為切片 。
4.4.1 切片
要創(chuàng)建切片,可指定要使用的第一個(gè)元素和最后一個(gè)元素的索引。與函數(shù)range() 一樣,Python在到達(dá)你指定的第二個(gè)索引前面的元素后停止。要輸出列表中的前三個(gè)元素,需要指定索引0~3,這將輸出分別為0 、1 和2 的元素。
- 使用[]進(jìn)行切片操作;
- 如果沒有指定第一個(gè)索引,Python將自動從列表開頭開始;
- 如果要讓切片終止于列表末尾,也可使用類似的語法;
- 負(fù)數(shù)索引返回離列表末尾相應(yīng)距離的元素,因此你可以輸出列表末尾的任何切片。
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print(players[0:3])
print(players[1:4])
print(players[:2])
print(players[3:])
print(players[-3:])
['charles', 'martina', 'michael']
['martina', 'michael', 'florence']
['charles', 'martina']
['florence', 'eli']
['michael', 'florence', 'eli']
4.4.2 遍歷切片
如果要遍歷列表的部分元素,可在for 循環(huán)中使用切片。
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("Here are the first three players on my team:")
for player in players[:3]:
print(player.title())
Here are the first three players on my team:
Charles
Martina
Michael
4.4.3 復(fù)制列表
要復(fù)制列表,可創(chuàng)建一個(gè)包含整個(gè)列表的切片,方法是同時(shí)省略起始索引和終止索引([:] )。這讓Python創(chuàng)建一個(gè)始于第一個(gè)元素,終止于最后一個(gè)元素的切片,即復(fù)制整個(gè)列表。
注意:這里與直接賦值不同,直接賦值類似于指針,指向的是同一段內(nèi)存地址。
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
print("My favorite foods are:")
print(my_foods)
print("My friend's favorite foods are:")
print(friend_foods)
My favorite foods are:
['pizza', 'falafel', 'carrot cake']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake']
#這里的my_foods和friend_foods是兩個(gè)不同的列表
my_foods = ['pizza', 'falafel', 'carrot cake']
friend_foods = my_foods[:]
my_foods.append('cannoli')
friend_foods.append('ice cream')
print("My favorite foods are:")
print(my_foods)
print("My friend's favorite foods are:")
print(friend_foods)
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'ice cream']
my_foods = ['pizza', 'falafel', 'carrot cake']
#這里則類似于指針,指向同一個(gè)內(nèi)存地址
friend_foods = my_foods
my_foods.append('cannoli')
friend_foods.append('ice cream')
print("My favorite foods are:")
print(my_foods)
print("My friend's favorite foods are:")
print(friend_foods)
My favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
My friend's favorite foods are:
['pizza', 'falafel', 'carrot cake', 'cannoli', 'ice cream']
練習(xí): 4-10 切片 :選擇你在本章編寫的一個(gè)程序,在末尾添加幾行代碼,以完成如下任務(wù)。
打印消息“The first three items in the list are:”,再使用切片來打印列表的前三個(gè)元素。
打印消息“Three items from the middle of the list are:”,再使用切片來打印列表中間的三個(gè)元素。
打印消息“The last three items in the list are:”,再使用切片來打印列表末尾的三個(gè)元素。
4-11 你的比薩和我的比薩 :在你為完成練習(xí)4-1而編寫的程序中,創(chuàng)建比薩列表的副本,并將其存儲到變量friend_pizzas 中,再完成如下任務(wù)。
在原來的比薩列表中添加一種比薩。
在列表friend_pizzas 中添加另一種比薩。
核實(shí)你有兩個(gè)不同的列表。為此,打印消息“My favorite pizzas are:”,再使用一個(gè)for 循環(huán)來打印第一個(gè)列表;打印消息“My friend's favorite pizzas are:”,再使用一個(gè)for 循環(huán)來打印第二個(gè)列表。核實(shí)新增的比薩被添加到了正確的列表中。
4-12 使用多個(gè)循環(huán) :在本節(jié)中,為節(jié)省篇幅,程序foods.py的每個(gè)版本都沒有使用for 循環(huán)來打印列表。請選擇一個(gè)版本的foods.py,在其中編寫兩個(gè)for 循環(huán),將各個(gè)食品列表都打印出來。
# 4-10
print("-----4-10-----")
players = ['charles', 'martina', 'michael', 'florence', 'eli']
print("The first three items in the list are: {}".format(players[:3]))
print("Three items from the middle of the list are: {}".format(players[int(len(players)/2)-1:int(len(players)/2)+2]))
print("The last three items in the list are: {}".format(players[-3:]))
# 4-11
print("-----4-11-----")
my_pizzas = ['pepperoni', 'chicken', 'pork']
friend_pizzas = my_pizzas[:]
my_pizzas.append('beacon')
friend_pizzas.append('cheese')
print("My favorite pizzas are: {}".format(my_pizzas))
print("My friend's favorite pizzas are: {}".format(friend_pizzas))
# 4-12
print("-----4-12-----")
for pizza in my_pizzas:
print(pizza,end='t')
-----4-10-----
The first three items in the list are: ['charles', 'martina', 'michael']
Three items from the middle of the list are: ['martina', 'michael', 'florence']
The last three items in the list are: ['michael', 'florence', 'eli']
-----4-11-----
My favorite pizzas are: ['pepperoni', 'chicken', 'pork', 'beacon']
My friend's favorite pizzas are: ['pepperoni', 'chicken', 'pork', 'cheese']
-----4-12-----
pepperoni chicken pork beacon
4.5 元組
列表是可以修改的,然而,有時(shí)候需要創(chuàng)建一系列不可修改的元素,元組可以滿足這種需求。
Python將不能修改的值稱為不可變的,而不可變的列表被稱為元組
。
4.5.1 定義元組
元組看起來猶如列表,但使用圓括號()
而不是方括號來標(biāo)識。定義元組后,就可以使用索引來訪問其元素,就像訪問列表元素一樣。
dimensions = (200, 50)
print(dimensions[0])
print(dimensions[1])
200
50
#嘗試修改內(nèi)容,將會報(bào)錯
dimensions = (200, 50)
dimensions[0] = 250
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-27-8d3115351a22 > in < module >()
1 #嘗試修改內(nèi)容,將會報(bào)錯
2 dimensions = (200, 50)
---- > 3 dimensions[0] = 250
TypeError: 'tuple' object does not support item assignment
4.5.2 遍歷元組中的所有值
和列表一樣,也可以使用for 循環(huán)來遍歷元組中的所有值。
dimensions = (200, 50)
for dimension in dimensions:
print(dimension)
200
50
4.5.3 修改元組變量
雖然不能修改元組的元素,但可以給儲元組的變量賦值。因此,如果要修改前述變量的大小,可重新定義整個(gè)元組。
相比于列表,元組是更簡單的數(shù)據(jù)結(jié)構(gòu)。如果需要存儲的一組值在程序的整個(gè)生命周期內(nèi)都不變,可使用元組。
dimensions = (200, 50)
print("Original dimensions:")
for dimension in dimensions:
print(dimension)
dimensions = (400, 100, 20)
print("Modified dimensions:")
for dimension in dimensions:
print(dimension)
Original dimensions:
200
50
Modified dimensions:
400
100
20
練習(xí): 4-13 自助餐 :有一家自助式餐館,只提供五種簡單的食品。請想出五種簡單的食品,并將其存儲在一個(gè)元組中。
使用一個(gè)for 循環(huán)將該餐館提供的五種食品都打印出來。
嘗試修改其中的一個(gè)元素,核實(shí)Python確實(shí)會拒絕你這樣做。
餐館調(diào)整了菜單,替換了它提供的其中兩種食品。請編寫一個(gè)這樣的代碼塊:給元組變量賦值,并使用一個(gè)for 循環(huán)將新元組的每個(gè)元素都打印出來。
# 4-13
print("-----4-13-----")
foods = ('milk', 'cola', 'coffee', 'egg', 'noodles')
for food in foods:
print(food, end="t")
print("n")
foods = ('water', 'cola', 'tea', 'egg', 'noodles')
for food in foods:
print(food, end="t")
foods[0]='cake'
-----4-13-----
milk cola coffee egg noodles
water cola tea egg noodles
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
< ipython-input-30-445179e5af1a > in < module >()
8 for food in foods:
9 print(food, end="t")
--- > 10 foods[0]='cake'
TypeError: 'tuple' object does not support item assignment
4.6 設(shè)置代碼格式
隨著程序越來越長,有必要了解一些代碼格式設(shè)置約定?;〞r(shí)間讓代碼盡可能易于閱讀;讓代碼易于閱讀有助于你掌握程序是做什么的,也可以幫助他人理解你編寫的代碼。
為確保所有人編寫的代碼的結(jié)構(gòu)都大致一致,Python程序員都遵循一些格式設(shè)置約定。學(xué)會編寫整潔的Python后,就能明白他人編寫的Python代碼的整體結(jié)構(gòu)——只要他們和你遵循相同的指南。要成為專業(yè)程序員,應(yīng)從現(xiàn)在開始就遵循這些指南,以養(yǎng)成良好的習(xí)慣。
4.6.1 格式設(shè)置指南
若要提出Python語言修改建議,需要編寫Python改進(jìn)提案(Python Enhancement Proposal,PEP)。PEP 8是最古老的PEP之一,它向Python程序員提供了代碼格式設(shè)置指南。PEP 8的篇幅很長,但大都與復(fù)雜的編碼結(jié)構(gòu)相關(guān)。
Python格式設(shè)置指南的編寫者深知,代碼被閱讀的次數(shù)比編寫的次數(shù)多。代碼編寫出來后,調(diào)試時(shí)你需要閱讀它;給程序添加新功能時(shí),需要花很長的時(shí)間閱讀代碼;與其他程序員分享代碼時(shí),這些程序員也將閱讀它們。
如果一定要在讓代碼易于編寫和易于閱讀之間做出選擇,Python程序員幾乎總是會選擇后者。下面的指南可幫助你從一開始就編寫出清晰的代碼。
4.6.2 縮進(jìn)
PEP 8建議每級縮進(jìn)都使用四個(gè)空格,這既可提高可讀性,又留下了足夠的多級縮進(jìn)空間。
在字處理文檔中,大家常常使用制表符而不是空格來縮進(jìn)。對于字處理文檔來說,這樣做的效果很好,但混合使用制表符和空格會讓Python解釋器感到迷惑。每款文本編輯器都提供了一種設(shè)置,可將輸入的制表符轉(zhuǎn)換為指定數(shù)量的空格。在編寫代碼時(shí)應(yīng)該使用制表符鍵,但一定要對編輯器進(jìn)行設(shè)置,使其在文檔中插入空格而不是制表符。
在程序中混合使用制表符和空格可能導(dǎo)致極難解決的問題。如果你混合使用了制表符和空格,可將文件中所有的制表符轉(zhuǎn)換為空格,大多數(shù)編輯器都提供了這樣的功能。
4.6.3 行長
很多Python程序員都建議每行不超過80字符。最初制定這樣的指南時(shí),在大多數(shù)計(jì)算機(jī)中,終端窗口每行只能容納79字符;當(dāng)前,計(jì)算機(jī)屏幕每行可容納的字符數(shù)多得多,為何還要使用79字符的標(biāo)準(zhǔn)行長呢?這里有別的原因。專業(yè)程序員通常會在同一個(gè)屏幕上打開多個(gè)文件,使用標(biāo)準(zhǔn)行長可以讓他們在屏幕上并排打開兩三個(gè)文件時(shí)能同時(shí)看到各個(gè)文件的完整行。PEP 8還建議注釋的行長都不超過72字符,因?yàn)橛行┕ぞ邽榇笮晚?xiàng)目自動生成文檔時(shí),會在每行注釋開頭添加格式化字符。
PEP 8中有關(guān)行長的指南并非不可逾越的紅線,有些小組將最大行長設(shè)置為99字符。在學(xué)習(xí)期間,你不用過多地考慮代碼的行長,但別忘了,協(xié)作編寫程序時(shí),大家?guī)缀醵甲袷豍EP 8指南。在大多數(shù)編輯器中,都可設(shè)置一個(gè)視覺標(biāo)志——通常是一條豎線,讓你知道不能越過的界線在什么地方。
附錄B介紹了如何配置文本編輯器,以使其:在你按制表符鍵時(shí)插入四個(gè)空格;顯示一條垂直參考線,幫助你遵守行長不能超過79字符的約定。
4.6.4 空行
要將程序的不同部分分開,可使用空行。你應(yīng)該使用空行來組織程序文件,但也不能濫用。
空行不會影響代碼的運(yùn)行,但會影響代碼的可讀性。Python解釋器根據(jù)水平縮進(jìn)情況來解讀代碼,但不關(guān)心垂直間距。
4.6.5 其他格式設(shè)置指南
PEP 8還有很多其他的格式設(shè)置建議,但這些指南針對的程序大都比目前為止本書提到的程序復(fù)雜。等介紹更復(fù)雜的Python結(jié)構(gòu)時(shí),我們再來分享相關(guān)的PEP 8指南。
練習(xí): 4-14 PEP 8 :請?jiān)L問https://python.org/dev/peps/pep-0008/ ,閱讀PEP 8格式設(shè)置指南。當(dāng)前,這些指南適用的不多,但你可以大致瀏覽一下。
評論
查看更多