本文參考《 Python 編程:從入門到實(shí)踐》一書,作者: [ 美 ] Eric Matthes
第1章 起步
1.1 搭建python環(huán)境
在不同的操作系統(tǒng)中, Python 存在細(xì)微的差別。
1.1.1 Python 2和Python 3
在本書中,將指出 Python 2 和 Python 3 的重大差別。
1.1.2 運(yùn)行Python代碼片段
1.1.3 Hello World程序
長(zhǎng)期以來(lái),編程界都認(rèn)為剛接觸一門新語(yǔ)言時(shí),如果首先使用它來(lái)編寫一個(gè)在屏幕上顯示消息“Hello World!”的程序,將給你帶來(lái)好運(yùn)。
只需一行代碼:
1.2 在不同操作系統(tǒng)中搭建 Python 編程環(huán)境
Python 是一種跨平臺(tái)的編程語(yǔ)言,這意味著它能夠運(yùn)行在所有主要的操作系統(tǒng)中。在所有安裝了 Python 的現(xiàn)代計(jì)算機(jī)上,都能夠運(yùn)行你編寫的任何 Python 程序。然而,在不同的操作系統(tǒng)中,安裝 Python 的方法存在細(xì)微的差別。
1.2.1 在 Linux 系統(tǒng)中搭建 Python 編程環(huán)境
1. 檢查 Python 版本
2. 安裝文本編輯器
Geany 是一款簡(jiǎn)單的文本編輯器:它易于安裝;讓你能夠直接運(yùn)行幾乎所有的程序(而無(wú)需通過(guò)終端來(lái)運(yùn)行);使用不同的顏色來(lái)顯示代碼,以突出代碼語(yǔ)法;在終端窗口中運(yùn)行代碼,讓你能夠習(xí)慣使用終端。
3. 運(yùn)行 Hello World 程序
4. 在終端會(huì)話中運(yùn)行 Python 代碼
1.2.2 在 OS X 系統(tǒng)中搭建 Python 編程環(huán)境
1. 檢查是否安裝了 Python
1.2.3 在 Windows 系統(tǒng)中搭建 Python 編程環(huán)境
Windows 系統(tǒng)并非都默認(rèn)安裝了 Python ,因此你可能需要下載并安裝它,再下載并安裝一個(gè)文本編輯器。
1. 安裝 Python
2. 啟動(dòng) Python 終端會(huì)話
3. 在終端會(huì)話中運(yùn)行 Python
4. 安裝文本編輯器
Geany 是一款簡(jiǎn)單的文本編輯器:它易于安裝;讓你能夠直接運(yùn)行幾乎所有的程序(而無(wú)需通過(guò)終端);使用不同的顏色來(lái)顯示代碼,以突出代碼語(yǔ)法;在終端窗口中運(yùn)行代碼,讓你能夠習(xí)慣使用終端。
5. 配置 Geany
6. 運(yùn)行 Hello World 程序
1.3 解決安裝問(wèn)題
1.4 從終端運(yùn)行 Python 程序
1.4.1 在 Linux 和 OS X 系統(tǒng)中從終端運(yùn)行 Python 程序
1.4.2 在 Windows 系統(tǒng)中從終端運(yùn)行 Python 程序
第 2 章 變量和簡(jiǎn)單數(shù)據(jù)類型
在本章中,你將學(xué)習(xí)可在 Python 程序中使用的各種數(shù)據(jù),還將學(xué)習(xí)如何將數(shù)據(jù)存儲(chǔ)到變量中,以及如何在程序中使用這些變量。
2.1 運(yùn)行 hello_world.py 時(shí)發(fā)生的情況
運(yùn)行 hello_world.py 時(shí), Python 都做了些什么呢?下面來(lái)深入研究一下。實(shí)際上,即便是運(yùn)行簡(jiǎn)單的程序, Python 所做的工作也相當(dāng)多:
運(yùn)行文件 hello_world.py 時(shí),末尾的 .py 指出這是一個(gè) Python 程序,因此編輯器將使用 Python 解釋器 來(lái)運(yùn)行它。 Python 解釋器讀取整個(gè)程序,確定其中每個(gè)單詞的含義。例如,看到單詞 print 時(shí),解釋器就會(huì)將括號(hào)中的內(nèi)容打印到屏幕,而不會(huì)管括號(hào)中的內(nèi)容是什么。
編寫程序時(shí),編輯器會(huì)以各種方式突出程序的不同部分。例如,它知道 print 是一個(gè)函數(shù)的名稱,因此將其顯示為藍(lán)色;它知道 “Hello Python world!” 不是 Python 代碼,因此將其顯示為橙色。這種功能稱為 語(yǔ)法突出 ,在你剛開(kāi)始編寫程序時(shí)很有幫助。
2.2 變量
2.2.1 變量的命名和使用
在 Python 中使用變量時(shí),需要遵守一些規(guī)則和指南。違反這些規(guī)則將引發(fā)錯(cuò)誤,而指南旨在讓你編寫的代碼更容易閱讀和理解。請(qǐng)務(wù)必牢記下述有關(guān)變量的規(guī)則。
變量名只能包含字母、數(shù)字和下劃線。變量名可以字母或下劃線打頭,但不能以數(shù)字打頭,例如,可將變量命名為 message_1 ,但不能將其命名為 1_message 。
變量名不能包含空格,但可使用下劃線來(lái)分隔其中的單詞。例如,變量名 greeting_message 可行,但變量名 greeting message 會(huì)引發(fā)錯(cuò)誤。
不要將 Python 關(guān)鍵字和函數(shù)名用作變量名,即不要使用 Python 保留用于特殊用途的單詞,如 print (請(qǐng)參見(jiàn)附錄 A.4 )。
變量名應(yīng)既簡(jiǎn)短又具有描述性。例如, name 比 n 好, student_name 比 s_n 好, name_length 比 length_of_persons_name 好。
慎用小寫字母 l 和大寫字母 O ,因?yàn)樗鼈兛赡鼙蝗隋e(cuò)看成數(shù)字 1 和 0 。
要?jiǎng)?chuàng)建良好的變量名,需要經(jīng)過(guò)一定的實(shí)踐,在程序復(fù)雜而有趣時(shí)尤其如此。隨著你編寫的程序越來(lái)越多,并開(kāi)始閱讀別人編寫的代碼,將越來(lái)越善于創(chuàng)建有意義的變量名。
注意:就目前而言,應(yīng)使用小寫的 Python 變量名。在變量名中使用大寫字母雖然不會(huì)導(dǎo)致錯(cuò)誤,但避免使用大寫字母是個(gè)不錯(cuò)的主意。
2.2.2 使用變量時(shí)避免命名錯(cuò)誤
我們將有意地編寫一些引發(fā)錯(cuò)誤的代碼。請(qǐng)輸入下面的代碼,包括其中拼寫不正確的單詞 mesage :
程序存在錯(cuò)誤時(shí), Python 解釋器將竭盡所能地幫助你找出問(wèn)題所在。程序無(wú)法成功地運(yùn)行時(shí),解釋器會(huì)提供一個(gè) traceback 。 traceback 是一條記錄,指出了解釋器嘗試運(yùn)行代碼時(shí),
在什么地方陷入了困境。下面是你不小心錯(cuò)誤地拼寫了變量名時(shí), Python 解釋器提供的 traceback :
解釋器指出,文件 hello_world.py 的第 2 行存在錯(cuò)誤(見(jiàn)?);
它列出了這行代碼,旨在幫助你快速找出錯(cuò)誤(見(jiàn)?);
它還指出了它發(fā)現(xiàn)的是什么樣的錯(cuò)誤(見(jiàn)?)。在這里,解釋器發(fā)現(xiàn)了一個(gè)名稱錯(cuò)誤,并指出打印的變量 mesage 未定義: Python 無(wú)法識(shí)別你提供的變量名。名稱錯(cuò)誤通常意味著兩種情況:要么是使用變量前忘記了給它賦值,要么是輸入變量名時(shí)拼寫不正確。
Python 解釋器不會(huì)對(duì)代碼做拼寫檢查,但要求變量名的拼寫一致。
很多編程錯(cuò)誤都很簡(jiǎn)單,只是在程序的某一行輸錯(cuò)了一個(gè)字符。為找出這種錯(cuò)誤而花費(fèi)很長(zhǎng)時(shí)間的大有人在。很多程序員天資聰穎、經(jīng)驗(yàn)豐富,卻為找出這種細(xì)微的錯(cuò)誤花費(fèi)數(shù)小時(shí)。你可能覺(jué)得這很好笑,但別忘了,在你的編程生涯中,經(jīng)常會(huì)有同樣的遭遇。
注意:要理解新的編程概念,最佳的方式是嘗試在程序中使用它們。如果你在做本書的練習(xí)時(shí)陷入了困境,請(qǐng)嘗試做點(diǎn)其他的事情。如果這樣做后依然無(wú)法擺脫困
境,請(qǐng)復(fù)習(xí)相關(guān)內(nèi)容。如果這樣做后情況依然如故,請(qǐng)參閱附錄 C 的建議。
2.3 字符串
字符串雖然看似簡(jiǎn)單,但能夠以很多不同的方式使用它們。
字符串 就是一系列字符。在 Python 中,用引號(hào)括起的都是字符串,其中的引號(hào)可以是單引號(hào),也可以是雙引號(hào),如下所示:
這種靈活性讓你能夠在字符串中包含引號(hào)和撇號(hào):
2.3.1 使用方法修改字符串的大小寫
輸出如下:
在這個(gè)示例中,小寫的字符串 'ada lovelace' 存儲(chǔ)到了變量 name 中。
在 print() 語(yǔ)句中,方法 title() 出現(xiàn)在這個(gè)變量的后面。
方法 是 Python 可對(duì)數(shù)據(jù)執(zhí)行的操作。
每個(gè)方法后面都跟著一對(duì)括號(hào),這是因?yàn)?/strong>方法通常需要額外的信息來(lái)完成其工作。這種信息是在括號(hào)內(nèi)提供的。
函數(shù) title() 不需要額外的信息,因此它后面的括號(hào)是空的。
title() 以首字母大寫的方式顯示每個(gè)單詞,即將每個(gè)單詞的首字母都改為大寫。這很有用!
還有其他幾個(gè)很有用的大小寫處理方法。例如,要將字符串改為全部大寫或全部小寫:
輸出如下:
存儲(chǔ)數(shù)據(jù)時(shí),方法 lower() 很有用。很多時(shí)候,你無(wú)法依靠用戶來(lái)提供正確的大小寫,因此需要將字符串先轉(zhuǎn)換為小寫,再存儲(chǔ)它們。以后需要顯示這些信息時(shí),再將其轉(zhuǎn)換為最合適的大小寫方式。
2.3.2 合并(拼接)字符串
Python 使用加號(hào)( + )來(lái)合并字符串。這種合并字符串的方法稱為 拼接 。通過(guò)拼接,可使用存儲(chǔ)在變量中的信息來(lái)創(chuàng)建完整的消息。
在這里,一個(gè)問(wèn)候用戶的句子中使用了全名(見(jiàn)?),并使用了方法 title() 來(lái)將姓名設(shè)置為合適的格式。這些代碼顯示一條格式良好的簡(jiǎn)單問(wèn)候語(yǔ):
你可以使用拼接來(lái)創(chuàng)建消息,再把整條消息都存儲(chǔ)在一個(gè)變量中:
這讓最后的 print 語(yǔ)句簡(jiǎn)單得多(見(jiàn)?)。
2.3.3 使用制表符或換行符來(lái)添加空白
在編程中, 空白 泛指任何非打印字符,如空格、制表符和換行符。你可使用空白來(lái)組織輸出,以使其更易讀。
要在字符串中添加制表符,可使用字符組合 \t
要在字符串中添加換行符,可使用字符組合 \n (這個(gè)就太熟悉了有木有^_^)
還可在同一個(gè)字符串中同時(shí)包含制表符和換行符。字符串 '\n\t' 讓 Python 換到下一行,并在下一行開(kāi)頭添加一個(gè)制表符。
2.3.4 刪除空白
在程序中,額外的空白可能令人迷惑。對(duì)程序員來(lái)說(shuō), 'python' 和 'python ' 看起來(lái)幾乎沒(méi)什么兩樣,但對(duì)程序來(lái)說(shuō),它們卻是兩個(gè)不同的字符串。 Python 能夠發(fā)現(xiàn) 'python ' 中額外的空白,并認(rèn)為它是有意義的 —— 除非你告訴它不是這樣的。
空白很重要,因?yàn)槟憬?jīng)常需要比較兩個(gè)字符串是否相同。例如,一個(gè)重要的示例是,在用戶登錄網(wǎng)站時(shí)檢查其用戶名。但在一些簡(jiǎn)單得多的情形下,額外的空格也可能令人迷惑。所幸在 Python 中,刪除用戶輸入的數(shù)據(jù)中的多余的空白易如反掌。
Python 能夠找出字符串開(kāi)頭和末尾多余的空白。要確保字符串末尾沒(méi)有空白,可使用方法 rstrip() 。
對(duì)變量 favorite_language 調(diào)用方法 rstrip() 后(見(jiàn)?),這個(gè)多余的空格被刪除了。然而,這種刪除只是暫時(shí)的,接下來(lái)再次詢問(wèn) favorite_language 的值時(shí),你會(huì)發(fā)現(xiàn)這個(gè)字符串與輸入時(shí)一樣,依然包含多余的空白(見(jiàn)?)。
要永久刪除這個(gè)字符串中的空白,必須將刪除操作的結(jié)果存回到變量中:
在編程中,經(jīng)常需要修改變量的值,再將新值存回到原來(lái)的變量中。這就是變量的值可能隨程序的運(yùn)行或用戶輸入數(shù)據(jù)而發(fā)生變化的原因。
還可以剔除字符串開(kāi)頭的空白,或同時(shí)剔除字符串兩端的空白。為此,可分別使用方法 lstrip() 和 rstrip() :
在實(shí)際程序中,這些剝除函數(shù)最常用于在存儲(chǔ)用戶輸入前對(duì)其進(jìn)行清理。
2.3.5 使用字符串時(shí)避免語(yǔ)法錯(cuò)誤
注意:編寫程序時(shí),編輯器的語(yǔ)法突出功能可幫助你快速找出某些語(yǔ)法錯(cuò)誤。看到 Python 代碼以普通句子的顏色顯示,或者普通句子以 Python 代碼的顏色顯示時(shí),就可能意味著文件中存在引號(hào)不匹配的情況。
2.3.6 Python 2 中的 print 語(yǔ)句
在 Python 2 中,無(wú)需將要打印的內(nèi)容放在括號(hào)內(nèi)。從技術(shù)上說(shuō), Python 3 中的 print 是一個(gè)函數(shù),因此括號(hào)必不可少。有些 Python 2 print 語(yǔ)句也包含括號(hào),但其行為與 Python 3 中稍有不同。簡(jiǎn)單地說(shuō),在 Python 2 代碼中,有些 print 語(yǔ)句包含括號(hào),有些不包含。
2.4 數(shù)字
在編程中,經(jīng)常使用數(shù)字來(lái)記錄游戲得分、表示可視化數(shù)據(jù)、存儲(chǔ) Web 應(yīng)用信息等。
2.4.1 整數(shù)
在 Python 中,可對(duì)整數(shù)執(zhí)行加( + )減( - )乘( * )除( / )運(yùn)算。
Python 使用兩個(gè)乘號(hào)(**)表示乘方運(yùn)算:
2.4.2 浮點(diǎn)數(shù)
浮點(diǎn)數(shù) 。大多數(shù)編程語(yǔ)言都使用了這個(gè)術(shù)語(yǔ),它指出了這樣一個(gè)事實(shí):小數(shù)點(diǎn)可出現(xiàn)在數(shù)字的任何位置(浮點(diǎn),即浮動(dòng)的點(diǎn))。
2.4.3 使用函數(shù) str() 避免類型錯(cuò)誤、
你可能認(rèn)為,上述代碼會(huì)打印一條簡(jiǎn)單的生日祝福語(yǔ): Happy 23rd birthday! 。但如果你運(yùn)行這些代碼,將發(fā)現(xiàn)它們會(huì)引發(fā)錯(cuò)誤:
這是一個(gè) 類型錯(cuò)誤 ,意味著 Python 無(wú)法識(shí)別你使用的信息。在這個(gè)示例中, Python 發(fā)現(xiàn)你使用了一個(gè)值為整數(shù)( int )的變量,但它不知道該如何解讀這個(gè)值(見(jiàn)?)。 Python 知
道,這個(gè)變量表示的可能是數(shù)值 23 ,也可能是字符 2 和 3 。像上面這樣在字符串中使用整數(shù)時(shí),需要顯式地指出你希望 Python 將這個(gè)整數(shù)用作字符串。為此,可調(diào)用函數(shù) str() ,
它讓 Python 將非字符串值表示為字符串:
這樣, Python 就知道你要將數(shù)值 23 轉(zhuǎn)換為字符串,進(jìn)而在生日祝福消息中顯示字符 2 和 3 。經(jīng)過(guò)上述處理后,將顯示你期望的消息,而不會(huì)引發(fā)錯(cuò)誤。
大多數(shù)情況下,在 Python 中使用數(shù)字都非常簡(jiǎn)單。如果結(jié)果出乎意料,請(qǐng)檢查 Python 是否按你期望的方式將數(shù)字解讀為了數(shù)值或字符串。
2.4.4 Python 2 中的整數(shù)
在 Python 2 中,將兩個(gè)整數(shù)相除得到的結(jié)果稍有不同:
Python 返回的結(jié)果為 1 ,而不是 1.5 。在 Python 2 中,整數(shù)除法的結(jié)果只包含整數(shù)部分,小數(shù)部分被刪除。請(qǐng)注意,計(jì)算整數(shù)結(jié)果時(shí),采取的方式不是四舍五入,而是將小數(shù)部分直接刪除。
在 Python 2 中,若要避免這種情況,務(wù)必確保至少有一個(gè)操作數(shù)為浮點(diǎn)數(shù),這樣結(jié)果也將為浮點(diǎn)數(shù):
從 Python 3 轉(zhuǎn)而用 Python 2 或從 Python 2 轉(zhuǎn)而用 Python 3 時(shí),這種除法行為常常會(huì)令人迷惑。使用或編寫同時(shí)使用浮點(diǎn)數(shù)和整數(shù)的代碼時(shí),一定要注意這種異常行為。
2.5 注釋
在大多數(shù)編程語(yǔ)言中,注釋都是一項(xiàng)很有用的功能。
2.5.1 如何編寫注釋
在 Python 中,注釋用井號(hào)( # )標(biāo)識(shí)。井號(hào)后面的內(nèi)容都會(huì)被 Python 解釋器忽略。
2.5.2 該編寫什么樣的注釋
編寫注釋的主要目的是闡述代碼要做什么,以及是如何做的。
在開(kāi)發(fā)項(xiàng)目期間,你對(duì)各個(gè)部分如何協(xié)同工作了如指掌,但過(guò)段時(shí)間后,有些細(xì)節(jié)你可能不記得了。當(dāng)然,你總是可以通過(guò)研究代碼來(lái)確定各個(gè)部分的工作原理,但通過(guò)編寫注釋,以清晰的自然語(yǔ)言對(duì)解決方案進(jìn)行概述,可節(jié)省很多時(shí)間。
要成為專業(yè)程序員或與其他程序員合作,就必須編寫有意義的注釋。
你最好從現(xiàn)在開(kāi)始就在程序中添加描述性注釋。作為新手,最值得養(yǎng)成的習(xí)慣之一是,在代碼中編寫清晰、簡(jiǎn)潔的注釋。
如果不確定是否要編寫注釋,就問(wèn)問(wèn)自己,找到合理的解決方案前,是否考慮了多個(gè)解決方案。如果答案是肯定的,就編寫注釋對(duì)你的解決方案進(jìn)行說(shuō)明吧。相比回過(guò)頭去再添加注釋,刪除多余的注釋要容易得多。
2.6 Python 之禪
編程語(yǔ)言 Perl 曾在互聯(lián)網(wǎng)領(lǐng)域長(zhǎng)期占據(jù)著統(tǒng)治地位,早期的大多數(shù)交互式網(wǎng)站使用的都是 Perl 腳本。彼時(shí), “ 解決問(wèn)題的辦法有多個(gè) ” 被 Perl 社區(qū)奉為座右銘。這種理念一度深受大家的喜愛(ài),因?yàn)檫@種語(yǔ)言固有的靈活性使得大多數(shù)問(wèn)題都有很多不同的解決之道。在開(kāi)發(fā)項(xiàng)目期間,這種靈活性是可以接受的,但大家最終認(rèn)識(shí)到,過(guò)于強(qiáng)調(diào)靈活性會(huì)導(dǎo)致大型項(xiàng)目難以維護(hù):要通過(guò)研究代碼搞清楚當(dāng)時(shí)解決復(fù)雜問(wèn)題的人是怎么想的,既困難又麻煩,還會(huì)耗費(fèi)大量的時(shí)間。
經(jīng)驗(yàn)豐富的程序員倡導(dǎo)盡可能避繁就簡(jiǎn)。 Python 社區(qū)的理念都包含在 Tim Peters 撰寫的 “Python 之禪 ” 中。要獲悉這些有關(guān)編寫優(yōu)秀 Python 代碼的指導(dǎo)原則,只需在解釋器中執(zhí)行命令 import this 。這里不打算贅述整個(gè) “Python 之禪 ” ,而只與大家分享其中的幾條原則,讓你明白為何它們對(duì) Python 新手來(lái)說(shuō)至關(guān)重要。
Python 程序員篤信代碼可以編寫得漂亮而優(yōu)雅。編程是要解決問(wèn)題的,設(shè)計(jì)良好、高效而漂亮的解決方案都會(huì)讓程序員心生敬意。隨著你對(duì) Python 的認(rèn)識(shí)越來(lái)越深入,并使用它來(lái)編寫越來(lái)越多的代碼,有一天也許會(huì)有人站在你后面驚呼: “ 哇,代碼編寫得真是漂亮!'
即便是復(fù)雜的代碼,也要讓它易于理解。開(kāi)發(fā)的項(xiàng)目涉及復(fù)雜代碼時(shí),一定要為這些代碼編寫有益的注釋。
如果讓兩名 Python 程序員去解決同一個(gè)問(wèn)題,他們提供的解決方案應(yīng)大致相同。這并不是說(shuō)編程沒(méi)有創(chuàng)意空間,而是恰恰相反!然而,大部分編程工作都是使用常見(jiàn)解決方案來(lái)解
決簡(jiǎn)單的小問(wèn)題,但這些小問(wèn)題都包含在更龐大、更有創(chuàng)意空間的項(xiàng)目中。在你的程序中,各種具體細(xì)節(jié)對(duì)其他 Python 程序員來(lái)說(shuō)都應(yīng)易于理解。
你可以將余生都用來(lái)學(xué)習(xí) Python 和編程的紛繁難懂之處,但這樣你什么項(xiàng)目都完不成。不要企圖編寫完美無(wú)缺的代碼;先編寫行之有效的代碼,再?zèng)Q定是對(duì)其做進(jìn)一步改進(jìn),還是轉(zhuǎn)而去編寫新代碼。
第 3 章 列表簡(jiǎn)介
列表讓你能夠在一個(gè)地方存儲(chǔ)成組的信息,其中可以只包含幾個(gè)元素,也可以包含數(shù)百萬(wàn)個(gè)元素。列表是新手可直接使用的最強(qiáng)大的 Python 功能之一,它融合了眾多重要的編程概念。
3.1 列表是什么
列表 由一系列按特定順序排列的元素組成。你可以創(chuàng)建包含字母表中所有字母、數(shù)字 0~9 或所有家庭成員姓名的列表;也可以將任何東西加入列表中,其中的元素之間可以沒(méi)有任何關(guān)系。
在 Python 中,用方括號(hào)( [] )來(lái)表示列表,并用逗號(hào)來(lái)分隔其中的元素。
3.1.1 訪問(wèn)列表元素
列表是有序集合,因此要訪問(wèn)列表的任何元素,只需將該元素的位置或索引告訴 Python 即可。要訪問(wèn)列表元素,可指出列表的名稱,再指出元素的索引,并將其放在方括號(hào)內(nèi)。
3.1.2 索引從 0 而不是 1 開(kāi)始
根據(jù)這種簡(jiǎn)單的計(jì)數(shù)方式,要訪問(wèn)列表的任何元素,都可將其位置減 1 ,并將結(jié)果作為索引。
Python 為訪問(wèn)最后一個(gè)列表元素提供了一種特殊語(yǔ)法。通過(guò)將索引指定為 -1 ,可讓 Python 返回最后一個(gè)列表元素:
這種約定也適用于其他負(fù)數(shù)索引,例如,索引 -2 返回倒數(shù)第二個(gè)列表元素,索引 -3 返回倒數(shù)第三個(gè)列表元素,以此類推。
3.1.3 使用列表中的各個(gè)值
3.2 修改、添加和刪除元素
你創(chuàng)建的大多數(shù)列表都將是動(dòng)態(tài)的,這意味著列表創(chuàng)建后,將隨著程序的運(yùn)行增刪元素。
3.2.1 修改列表元素
3.2.2 在列表中添加元素
1. 在列表末尾添加元素
使用方法 append() 將元素 添加到列表末尾。
方法 append() 讓動(dòng)態(tài)地創(chuàng)建列表易如反掌,例如,你可以先創(chuàng)建一個(gè)空列表,再使用一系列的 append() 語(yǔ)句添加元素。下面來(lái)創(chuàng)建一個(gè)空列表,再在其中添加元素 'honda' 、 'yamaha' 和 'suzuki' :
這種創(chuàng)建列表的方式極其常見(jiàn),因?yàn)榻?jīng)常要等程序運(yùn)行后,你才知道用戶要在程序中存儲(chǔ)哪些數(shù)據(jù)。為控制用戶,可首先創(chuàng)建一個(gè)空列表,用于存儲(chǔ)用戶將要輸入的值,然后將用戶提供的每個(gè)新值附加到列表中。
2. 在列表中插入元素
使用方法 insert() 可在列表的任何位置添加新元素。為此,你需要指定新元素的索引和值。
這種操作將列表中既有的每個(gè)元素都右移一個(gè)位置:
3.2.3 從列表中刪除元素
1. 使用 del 語(yǔ)句刪除元素
如果知道要?jiǎng)h除的元素在列表中的位置,可使用 del 語(yǔ)句。
看下結(jié)果:
使用 del 可刪除任何位置處的列表元素,條件是知道其索引。
使用 del 語(yǔ)句將值從列表中刪除后,你就無(wú)法再訪問(wèn)它了。
2. 使用方法 pop() 刪除元素
有時(shí)候,你要將元素從列表中刪除,并接著使用它的值。
方法 pop() 可刪除列表末尾的元素,并讓你能夠接著使用它。術(shù)語(yǔ) 彈出 ( pop )源自這樣的類比:列表就像一個(gè)棧,而刪除列表末尾的元素相當(dāng)于彈出棧頂元素。
我們首先定義并打印了列表 motorcycles (見(jiàn)?)。接下來(lái),我們從這個(gè)列表中彈出一個(gè)值,并將其存儲(chǔ)到變量 popped_motorcycle 中(見(jiàn)?)。然后我們打印這個(gè)列
表,以核實(shí)從其中刪除了一個(gè)值(見(jiàn)?)。最后,我們打印彈出的值,以證明我們依然能夠訪問(wèn)被刪除的值(見(jiàn)?)。
輸出表明,列表末尾的值 'suzuki' 已刪除,它現(xiàn)在存儲(chǔ)在變量 popped_motorcycle 中:
3. 彈出列表中任何位置處的元素
實(shí)際上,你可以使用 pop() 來(lái)刪除列表中任何位置的元素,只需在括號(hào)中指定要?jiǎng)h除的元素的索引即可。
別忘了,每當(dāng)你使用 pop() 時(shí),被彈出的元素就不再在列表中了。
如果你不確定該使用 del 語(yǔ)句還是 pop() 方法,下面是一個(gè)簡(jiǎn)單的判斷標(biāo)準(zhǔn):
如果你要從列表中刪除一個(gè)元素,且不再以任何方式使用它,就使用 del 語(yǔ)句;如果你要在刪除元素后還能繼續(xù)使用它,就使用方法 pop() 。
4. 根據(jù)值刪除元素
有時(shí)候,你不知道要從列表中刪除的值所處的位置。如果你只知道要?jiǎng)h除的元素的值,可使用方法 remove() 。
使用 remove() 從列表中刪除元素時(shí),也可接著使用它的值。
注意 方法 remove() 只刪除第一個(gè)指定的值。如果要?jiǎng)h除的值可能在列表中出現(xiàn)多次,就需要使用循環(huán)來(lái)判斷是否刪除了所有這樣的值。
3.3 組織列表
在你創(chuàng)建的列表中,元素的排列順序常常是無(wú)法預(yù)測(cè)的,因?yàn)槟悴⒎强偰芸刂朴脩籼峁?shù)據(jù)的順序。
3.3.1 使用方法 sort() 對(duì)列表進(jìn)行永久性排序
方法 sort() (見(jiàn)?)永久性地修改了列表元素的排列順序。現(xiàn)在,汽車是按字母順序排列的,再也無(wú)法恢復(fù)到原來(lái)的排列順序:
你還可以按與字母順序相反的順序排列列表元素,為此,只需向 sort() 方法傳遞參數(shù) reverse=True 。
3.3.2 使用函數(shù) sorted() 對(duì)列表進(jìn)行臨時(shí)排序
要保留列表元素原來(lái)的排列順序,同時(shí)以特定的順序呈現(xiàn)它們,可使用函數(shù) sorted() 。函數(shù) sorted() 讓你能夠按特定順序顯示列表元素,同時(shí)不影響它們?cè)诹斜碇械脑寂帕许樞?/strong>。
注意,調(diào)用函數(shù) sorted() 后,列表元素的排列順序并沒(méi)有變(見(jiàn)?)。如果你要按與字母順序相反的順序顯示列表,也可向函數(shù) sorted() 傳遞參數(shù) reverse=True 。
注意 在并非所有的值都是小寫時(shí),按字母順序排列列表要復(fù)雜些。決定排列順序時(shí),有多種解讀大寫字母的方式,要指定準(zhǔn)確的排列順序,可能比我們這里所做的要復(fù)雜。
3.3.3 倒著打印列表
要反轉(zhuǎn)列表元素的排列順序,可使用方法 reverse() 。
注意, reverse() 不是指按與字母順序相反的順序排列列表元素,而只是反轉(zhuǎn)列表元素的排列順序。
方法 reverse() 永久性地修改列表元素的排列順序,但可隨時(shí)恢復(fù)到原來(lái)的排列順序,為此只需對(duì)列表再次調(diào)用 reverse() 即可。
3.3.4 確定列表的長(zhǎng)度
使用函數(shù) len() 可快速獲悉列表的長(zhǎng)度。
注意 Python 計(jì)算列表元素?cái)?shù)時(shí)從 1 開(kāi)始,因此確定列表長(zhǎng)度時(shí),你應(yīng)該不會(huì)遇到差一錯(cuò)誤。
3.4 使用列表時(shí)避免索引錯(cuò)誤
索引錯(cuò)誤意味著 Python 無(wú)法理解你指定的索引。程序發(fā)生索引錯(cuò)誤時(shí),請(qǐng)嘗試將你指定的索引減 1 ,然后再次運(yùn)行程序,看看結(jié)果是否正確。
別忘了,每當(dāng)需要訪問(wèn)最后一個(gè)列表元素時(shí),都可使用索引 -1 。這在任何情況下都行之有效,即便你最后一次訪問(wèn)列表后,其長(zhǎng)度發(fā)生了變化:
注意 發(fā)生索引錯(cuò)誤卻找不到解決辦法時(shí),請(qǐng)嘗試將列表或其長(zhǎng)度打印出來(lái)。列表可能與你以為的截然不同,在程序?qū)ζ溥M(jìn)行了動(dòng)態(tài)處理時(shí)尤其如此。通過(guò)查看列表或其包含的元素?cái)?shù),可幫助你找出這種邏輯錯(cuò)誤。
第 4 章 操作列表
在本章中,你將學(xué)習(xí)如何 遍歷 整個(gè)列表,這只需要幾行代碼,無(wú)論列表有多長(zhǎng)。循環(huán)讓你能夠?qū)α斜淼拿總€(gè)元素都采取一個(gè)或一系列相同的措施,從而高效地處理任何長(zhǎng)度的列表,包括包含數(shù)千乃至數(shù)百萬(wàn)個(gè)元素的列表。
4.1 遍歷整個(gè)列表
需要對(duì)列表中的每個(gè)元素都執(zhí)行相同的操作時(shí),可使用 Python 中的 for 循環(huán)。
我們定義了一個(gè) for 循環(huán)(見(jiàn)?);這行代碼讓 Python 從列表 magicians 中取出一個(gè)名字,并將其存儲(chǔ)在變量 magician 中。
最后,我們讓 Python 打印前面存儲(chǔ)到變量 magician 中的名字(見(jiàn)?)。
4.1.1 深入地研究循環(huán)
循環(huán)這種概念很重要,因?yàn)樗?strong>讓計(jì)算機(jī)自動(dòng)完成重復(fù)工作的常見(jiàn)方式之一。
剛開(kāi)始使用循環(huán)時(shí)請(qǐng)牢記,對(duì)列表中的每個(gè)元素,都將執(zhí)行循環(huán)指定的步驟,而不管列表包含多少個(gè)元素。如果列表包含一百萬(wàn)個(gè)元素, Python 就重復(fù)執(zhí)行指定的步驟一百萬(wàn)次,且通常速度非常快。
4.1.2 在 for 循環(huán)中執(zhí)行更多的操作
在 for 循環(huán)中,可對(duì)每個(gè)元素執(zhí)行任何操作。下面來(lái)擴(kuò)展前面的示例,對(duì)于每位魔術(shù)師,都打印一條消息,指出他的表演太精彩了。
相比于前一個(gè)示例,唯一的不同是對(duì)于每位魔術(shù)師,都打印了一條以其名字為抬頭的消息(見(jiàn)?)。這個(gè)循環(huán)第一次迭代時(shí),變量 magician 的值為 'alice' ,因此 Python 打印的第一條消息的抬頭為 'Alice' 。第二次迭代時(shí),消息的抬頭為 'David' ,而第三次迭代時(shí),抬頭為 'Carolina' 。
下面的輸出表明,對(duì)于列表中的每位魔術(shù)師,都打印了一條個(gè)性化消息:
在 for 循環(huán)中,想包含多少行代碼都可以。在代碼行 for magician in magicians 后面,每個(gè)縮進(jìn)的代碼行都是循環(huán)的一部分,且將針對(duì)列表中的每個(gè)值都執(zhí)行一次。因此,可對(duì)列表中的每個(gè)值執(zhí)行任意次數(shù)的操作。
由于兩條 print 語(yǔ)句都縮進(jìn)了,因此它們都將針對(duì)列表中的每位魔術(shù)師執(zhí)行一次。第二條 print 語(yǔ)句中的換行符 '\n' (見(jiàn)?)在每次迭代結(jié)束后都插入一個(gè)空行,從而整潔地將針對(duì)各位魔術(shù)師的消息編組:
4.1.3 在 for 循環(huán)結(jié)束后執(zhí)行一些操作
4.2 避免縮進(jìn)錯(cuò)誤
4.2.1 忘記縮進(jìn)
對(duì)于位于 for 語(yǔ)句后面且屬于循環(huán)組成部分的代碼行,一定要縮進(jìn)。如果你忘記縮進(jìn), Python 會(huì)提醒你:
print 語(yǔ)句(見(jiàn)?)應(yīng)縮進(jìn)卻沒(méi)有縮進(jìn)。 Python 沒(méi)有找到期望縮進(jìn)的代碼塊時(shí),會(huì)讓你知道哪行代碼有問(wèn)題。
4.2.2 忘記縮進(jìn)額外的代碼行
4.2.3 不必要的縮進(jìn)
4.2.4 循環(huán)后不必要的縮進(jìn)
4.2.5 遺漏了冒號(hào)
4.3 創(chuàng)建數(shù)值列表
列表非常適合用于存儲(chǔ)數(shù)字集合,而 Python 提供了很多工具,可幫助你高效地處理數(shù)字列表。明白如何有效地使用這些工具后,即便列表包含數(shù)百萬(wàn)個(gè)元素,你編寫的代碼也能運(yùn)行得很好。
4.3.1 使用函數(shù) range()
Python 函數(shù) range() 讓你能夠輕松地生成一系列的數(shù)字。
在這個(gè)示例中, range() 只是打印數(shù)字 1~4 ,這是你在編程語(yǔ)言中經(jīng)常看到的差一行為的結(jié)果。函數(shù) range() 讓 Python 從你指定的第一個(gè)值開(kāi)始數(shù),并在到達(dá)你指定的第二個(gè)值后停止,因此輸出不包含第二個(gè)值(這里為 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í),還可指定步長(zhǎng)。
在這個(gè)示例中,函數(shù) range() 從 2 開(kāi)始數(shù),然后不斷地加 2 ,直到達(dá)到或超過(guò)終值( 11 ),因此輸出如下:
使用函數(shù) range() 幾乎能夠創(chuàng)建任何需要的數(shù)字集,例如,如何創(chuàng)建一個(gè)列表,其中包含前 10 個(gè)整數(shù)(即 1~10 )的平方呢?在 Python 中,兩個(gè)星號(hào)( ** )表示乘方運(yùn)算。下面的代碼演示了如何將前 10 個(gè)整數(shù)的平方加入到一個(gè)列表中:
首先,我們創(chuàng)建了一個(gè)空列表(見(jiàn)?);接下來(lái),使用函數(shù) range() 讓 Python 遍歷 1~10 的值(見(jiàn)?)。在循環(huán)中,計(jì)算當(dāng)前值的平方,并將結(jié)果存儲(chǔ)到變量 square 中(見(jiàn)?)。然后,將新計(jì)算得到的平方值附加到列表 squares 末尾(見(jiàn)?)。最后,循環(huán)結(jié)束后,打印列表 squares (見(jiàn)?):
為讓這些代碼更簡(jiǎn)潔,可不使用臨時(shí)變量 square ,而直接將每個(gè)計(jì)算得到的值附加到列表末尾:
squares=[]for value in range(1,11): square=value**2 squares.append(square)print(squares)
創(chuàng)建更復(fù)雜的列表時(shí),可使用上述兩種方法中的任何一種。有時(shí)候,使用臨時(shí)變量會(huì)讓代碼更易讀;而在其他情況下,這樣做只會(huì)讓代碼無(wú)謂地變長(zhǎng)。你首先應(yīng)該考慮的是,編寫清晰易懂且能完成所需功能的代碼;等到審核代碼時(shí),再考慮采用更高效的方法。
4.3.3 對(duì)數(shù)字列表執(zhí)行簡(jiǎn)單的統(tǒng)計(jì)計(jì)算
有幾個(gè)專門用于處理數(shù)字列表的 Python 函數(shù)。例如,你可以輕松地找出數(shù)字列表的最大值、最小值和總和:
4.3.4 列表解析
前面介紹的生成列表 squares 的方式包含三四行代碼,而列表解析讓你只需編寫一行代碼就能生成這樣的列表。 列表解析 將 for 循環(huán)和創(chuàng)建新元素的代碼合并成一行,并自動(dòng)附加新元素。
要使用這種語(yǔ)法,首先指定一個(gè)描述性的列表名,如 squares ;
然后,指定一個(gè)左方括號(hào),并定義一個(gè)表達(dá)式,用于生成你要存儲(chǔ)到列表中的值。在這個(gè)示例中,表達(dá)式為 value**2 ,它計(jì)算平方值。
接下來(lái),編寫一個(gè) for 循環(huán),用于給表達(dá)式提供值,再加上右方括號(hào)。在這個(gè)示例中, for 循環(huán)為 for value in range(1,11) ,它將值1~10 提供給表達(dá)式 value**2 。請(qǐng)注意,這里的 for 語(yǔ)句末尾沒(méi)有冒號(hào)。
4.4 使用列表的一部分
在本章中,你一直在學(xué)習(xí)如何處理列表的所有元素。你還可以處理列表的部分元素 ——Python 稱之為 切片 。
4.4.1 切片
要?jiǎng)?chuàng)建切片,可指定要使用的第一個(gè)元素和最后一個(gè)元素的索引。與函數(shù) range() 一樣, Python 在到達(dá)你指定的第二個(gè)索引前面的元素后停止。
如果你沒(méi)有指定第一個(gè)索引, Python 將自動(dòng)從列表開(kāi)頭開(kāi)始:
本書前面說(shuō)過(guò),負(fù)數(shù)索引返回離列表末尾相應(yīng)距離的元素,因此你可以輸出列表末尾的任何切片。例如,如果你要輸出名單上的最后三名隊(duì)員,可使用切片 players[-3:] :
4.4.2 遍歷切片
如果要遍歷列表的部分元素,可在 for 循環(huán)中使用切片。
4.4.3 復(fù)制列表
要復(fù)制列表,可創(chuàng)建一個(gè)包含整個(gè)列表的切片,方法是同時(shí)省略起始索引和終止索引( [:] )。這讓 Python 創(chuàng)建一個(gè)始于第一個(gè)元素,終止于最后一個(gè)元素的切片,即復(fù)制整個(gè)列表。
下例演示了在不使用切片的情況下復(fù)制列表的情況:
這里將 my_foods 賦給 friend_foods ,而不是將 my_foods 的副本存儲(chǔ)到 friend_foods (見(jiàn)?)。這種語(yǔ)法實(shí)際上是讓 Python 將新變量 friend_foods 關(guān)聯(lián)到包含在 my_foods 中的列表,因此這兩個(gè)變量都指向同一個(gè)列表。鑒于此,當(dāng)我們將 'cannoli' 添加到 my_foods 中時(shí),它也將出現(xiàn)在 friend_foods 中;同樣,雖然 'icecream' 好像只被加入到了 friend_foods 中,但它也將出現(xiàn)在這兩個(gè)列表中。
注意 現(xiàn)在暫時(shí)不要考慮這個(gè)示例中的細(xì)節(jié)。基本上,當(dāng)你試圖使用列表的副本時(shí),如果結(jié)果出乎意料,請(qǐng)確認(rèn)你像第一個(gè)示例那樣使用切片復(fù)制了列表。
4.5 元組
列表非常適合用于存儲(chǔ)在程序運(yùn)行期間可能變化的數(shù)據(jù)集。
列表是可以修改的,然而,有時(shí)候你需要?jiǎng)?chuàng)建一系列不可修改的元素,元組可以滿足這種需求。 Python 將不能修改的值稱為 不可變的 ,而不可變的列表被稱為元組。
4.5.1 定義元組
元組看起來(lái)猶如列表,但使用圓括號(hào)而不是方括號(hào)來(lái)標(biāo)識(shí)。定義元組后,就可以使用索引來(lái)訪問(wèn)其元素,就像訪問(wèn)列表元素一樣。
例如,如果有一個(gè)大小不應(yīng)改變的矩形,可將其長(zhǎng)度和寬度存儲(chǔ)在一個(gè)元組中,從而確保它們是不能修改的:
?處的代碼試圖修改第一個(gè)元素的值,導(dǎo)致 Python 返回類型錯(cuò)誤消息。由于試圖修改元組的操作是被禁止的,因此 Python 指出不能給元組的元素賦值:
4.5.2 遍歷元組中的所有值
4.5.3 修改元組變量
雖然不能修改元組的元素,但可以給存儲(chǔ)元組的變量賦值。因此,如果要修改前述矩形的尺寸,可重新定義整個(gè)元組:
相比于列表,元組是更簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)。如果需要存儲(chǔ)的一組值在程序的整個(gè)生命周期內(nèi)都不變,可使用元組。
4.6 設(shè)置代碼格式
隨著你編寫的程序越來(lái)越長(zhǎng),有必要了解一些代碼格式設(shè)置約定。請(qǐng)花時(shí)間讓你的代碼盡可能易于閱讀;讓代碼易于閱讀有助于你掌握程序是做什么的,也可以幫助他人理解你編寫的代碼。
要成為專業(yè)程序員,應(yīng)從現(xiàn)在開(kāi)始就遵循這些指南,以養(yǎng)成良好的習(xí)慣。
4.6.1 格式設(shè)置指南
若要提出 Python 語(yǔ)言修改建議,需要編寫 Python 改進(jìn)提案 ( Python Enhancement Proposal , PEP )。 PEP 8 是最古老的 PEP 之一,它向 Python 程序員提供了代碼格式設(shè)置指南。 PEP 8 的篇幅很長(zhǎng),但大都與復(fù)雜的編碼結(jié)構(gòu)相關(guān)。
如果一定要在讓代碼易于編寫和易于閱讀之間做出選擇, Python 程序員幾乎總是會(huì)選擇后者。
4.6.2 縮進(jìn)
PEP 8 建議每級(jí)縮進(jìn)都使用四個(gè)空格,這既可提高可讀性,又留下了足夠的多級(jí)縮進(jìn)空間。
在字處理文檔中,大家常常使用制表符而不是空格來(lái)縮進(jìn)。
對(duì)于字處理文檔來(lái)說(shuō),這樣做的效果很好,但混合使用制表符和空格會(huì)讓 Python 解釋器感到迷惑。
每款文本編輯器都提供了一種設(shè)置,可將輸入的制表符轉(zhuǎn)換為指定數(shù)量的空格。
你在編寫代碼時(shí)應(yīng)該使用制表符鍵,但一定要對(duì)編輯器進(jìn)行設(shè)置,使其在文檔中插入空格而不是制表符。
在程序中混合使用制表符和空格可能導(dǎo)致極難解決的問(wèn)題。如果你混合使用了制表符和空格,可將文件中所有的制表符轉(zhuǎn)換為空格,大多數(shù)編輯器都提供了這樣的功能。
4.6.3 行長(zhǎng)
很多 Python 程序員都建議每行不超過(guò) 80 字符。
PEP 8 還建議注釋的行長(zhǎng)都不超過(guò) 72 字符,因?yàn)?/strong>有些工具為大型項(xiàng)目自動(dòng)生成文檔時(shí),會(huì)在每行注釋開(kāi)頭添加格式化字符。
在學(xué)習(xí)期間,你不用過(guò)多地考慮代碼的行長(zhǎng),但別忘了,協(xié)作編寫程序時(shí),大家?guī)缀?strong>都遵守PEP 8 指南。
在大多數(shù)編輯器中,都可設(shè)置一個(gè)視覺(jué)標(biāo)志 —— 通常是一條豎線,讓你知道不能越過(guò)的界線在什么地方。
注意 附錄 B 介紹了如何配置文本編輯器,以使其:在你按制表符鍵時(shí)插入四個(gè)空格;顯示一條垂直參考線,幫助你遵守行長(zhǎng)不能超過(guò) 79 字符的約定。
4.6.4 空行
要將程序的不同部分分開(kāi),可使用空行。你應(yīng)該使用空行來(lái)組織程序文件,但也不能濫用。
空行不會(huì)影響代碼的運(yùn)行,但會(huì)影響代碼的可讀性。 Python 解釋器根據(jù)水平縮進(jìn)情況來(lái)解讀代碼,但不關(guān)心垂直間距。
請(qǐng)?jiān)L問(wèn) https://python.org/dev/peps/pep-0008/ ,閱讀 PEP 8 格式設(shè)置指南。當(dāng)前,這些指南適用的不多,但你可以大致瀏覽一下。
第 5 章 if 語(yǔ)句
5.1 一個(gè)簡(jiǎn)單示例
5.2 條件測(cè)試
每條 if 語(yǔ)句的核心都是一個(gè)值為 True 或 False 的表達(dá)式,這種表達(dá)式被稱為 條件測(cè)試。
5.2.1 檢查是否相等
一個(gè)等號(hào)是陳述;對(duì)于?處的代碼,可解讀為 “ 將變量 car 的值設(shè)置為 'audi' ” 。兩個(gè)等號(hào)是發(fā)問(wèn);對(duì)于?處的代碼,可解讀為 “ 變量 car 的值是 'bmw' 嗎? ” 。
5.2.2 檢查是否相等時(shí)不考慮大小寫
在 Python 中檢查是否相等時(shí)區(qū)分大小寫,例如,兩個(gè)大小寫不同的值會(huì)被視為不相等:
如果大小寫很重要,這種行為有其優(yōu)點(diǎn)。但如果大小寫無(wú)關(guān)緊要,而只想檢查變量的值,可將變量的值轉(zhuǎn)換為小寫,再進(jìn)行比較:
函數(shù) lower() 不會(huì)修改存儲(chǔ)在變量 car 中的值:
5.2.3 檢查是否不相等
要判斷兩個(gè)值是否不等,可結(jié)合使用驚嘆號(hào)和等號(hào)( != ),其中的驚嘆號(hào)表示 不。
我們將把要求的比薩配料存儲(chǔ)在一個(gè)變量中,再打印一條消息,指出顧客要求的配料是否是意式小銀魚( anchovies ):
你編寫的大多數(shù)條件表達(dá)式都檢查兩個(gè)值是否相等,但有時(shí)候檢查兩個(gè)值是否不等的效率更高。
5.2.4 比較數(shù)字
條件語(yǔ)句中可包含各種數(shù)學(xué)比較,如小于、小于等于、大于、大于等于:
5.2.5 檢查多個(gè)條件
你可能想同時(shí)檢查多個(gè)條件,例如,有時(shí)候你需要在兩個(gè)條件都為 True 時(shí)才執(zhí)行相應(yīng)的操作,而有時(shí)候你只要求一個(gè)條件為 True 時(shí)就執(zhí)行相應(yīng)的操作。在這些情況下,關(guān)鍵字 and 和 or 可助你一臂之力。
1. 使用 and 檢查多個(gè)條件
為改善可讀性,可將每個(gè)測(cè)試都分別放在一對(duì)括號(hào)內(nèi),但并非必須這樣做。如果你使用括號(hào),測(cè)試將類似于下面這樣:
2. 使用 or 檢查多個(gè)條件
關(guān)鍵字 or 也能夠讓你檢查多個(gè)條件,但只要至少有一個(gè)條件滿足,就能通過(guò)整個(gè)測(cè)試。僅當(dāng)兩個(gè)測(cè)試都沒(méi)有通過(guò)時(shí),使用 or 的表達(dá)式才為 False 。
5.2.6 檢查特定值是否包含在列表中
有時(shí)候,執(zhí)行操作前必須檢查列表是否包含特定的值。例如,結(jié)束用戶的注冊(cè)過(guò)程前,可能需要檢查他提供的用戶名是否已包含在用戶名列表中。在地圖程序中,可能需要檢查用戶提交的位置是否包含在已知位置列表中。
要判斷特定的值是否已包含在列表中,可使用關(guān)鍵字 in 。來(lái)看你可能為比薩店編寫的一些代碼;這些代碼首先創(chuàng)建一個(gè)列表,其中包含用戶點(diǎn)的比薩配料,然后檢查特定的配料是否包含在該列表中。
這種技術(shù)很有用,它讓你能夠在創(chuàng)建一個(gè)列表后,輕松地檢查其中是否包含特定的值。
5.2.7 檢查特定值是否不包含在列表中
還有些時(shí)候,確定特定的值未包含在列表中很重要;在這種情況下,可使用關(guān)鍵字 not in 。
5.2.8 布爾表達(dá)式
術(shù)語(yǔ) 布爾表達(dá)式 ,它不過(guò)是條件測(cè)試的別名。與條件表達(dá)式一樣,布爾表達(dá)式的結(jié)果要么為 True ,要么為 False 。
在跟蹤程序狀態(tài)或程序中重要的條件方面,布爾值提供了一種高效的方式。
5.3 if 語(yǔ)句
5.3.1 簡(jiǎn)單的 if 語(yǔ)句
假設(shè)有一個(gè)表示某人年齡的變量,而你想知道這個(gè)人是否夠投票的年齡,可使用如下代碼:
5.3.2 if-else 語(yǔ)句
if-else 結(jié)構(gòu)非常適合用于要讓 Python 執(zhí)行兩種操作之一的情形。
5.3.3 if-elif-else 結(jié)構(gòu)
如果只使用一條 if 語(yǔ)句,如何確定門票價(jià)格呢?
為讓代碼更簡(jiǎn)潔,可不在 if-elif-else 代碼塊中打印門票價(jià)格,而只在其中設(shè)置門票價(jià)格,并在它后面添加一條簡(jiǎn)單的 print 語(yǔ)句:
1 age=252 if age<4:3 price=04 elif age<18:5 price=56 else:7 price=108 print('Your adminission cost is $'+str(price)+'.')
這些代碼的輸出與前一個(gè)示例相同,但 if-elif-else 結(jié)構(gòu)的作用更小,它只確定門票價(jià)格,而不是在確定門票價(jià)格的同時(shí)打印一條消息。除效率更高外,這些修訂后的代碼
還更容易修改:要調(diào)整輸出消息的內(nèi)容,只需修改一條而不是三條 print 語(yǔ)句。
5.3.4 使用多個(gè) elif 代碼塊
假設(shè)對(duì)于 65 歲(含)以上的老人,可以半價(jià)(即 5 美元)購(gòu)買門票:
5.3.5 省略 else 代碼塊
Python 并不要求 if-elif 結(jié)構(gòu)后面必須有 else 代碼塊。在有些情況下, else 代碼塊很有用;而在其他一些情況下,使用一條 elif 語(yǔ)句來(lái)處理特定的情形更清晰:
1 age=99 2 if age<4: 3 price=0 4 elif age<18: 5 price=5 6 elif age<65: 7 price=10 8 elif age>=65: 9 price=510 print('Your adminission cost is $'+str(price)+'.')
else 是一條包羅萬(wàn)象的語(yǔ)句,只要不滿足任何 if 或 elif 中的條件測(cè)試,其中的代碼就會(huì)執(zhí)行,這可能會(huì)引入無(wú)效甚至惡意的數(shù)據(jù)。如果知道最終要測(cè)試的條件,應(yīng)考慮使用一個(gè) elif 代碼塊來(lái)代替 else 代碼塊。這樣,你就可以肯定,僅當(dāng)滿足相應(yīng)的條件時(shí),你的代碼才會(huì)執(zhí)行。(這些編程設(shè)計(jì)思想很有用)
5.3.6 測(cè)試多個(gè)條件
if-elif-else 結(jié)構(gòu)功能強(qiáng)大,但僅適合用于只有一個(gè)條件滿足的情況:遇到通過(guò)了的測(cè)試后, Python 就跳過(guò)余下的測(cè)試。這種行為很好,效率很高,讓你能夠測(cè)試一個(gè)特定的
條件。
然而,有時(shí)候必須檢查你關(guān)心的所有條件。在這種情況下,應(yīng)使用一系列不包含 elif 和 else 代碼塊的簡(jiǎn)單 if 語(yǔ)句。在可能有多個(gè)條件為 True ,且你需要在每個(gè)條件為 True
時(shí)都采取相應(yīng)措施時(shí),適合使用這種方法。
下面再來(lái)看前面的比薩店示例。如果顧客點(diǎn)了兩種配料,就需要確保在其比薩中包含這些配料:
如果像下面這樣轉(zhuǎn)而使用 if-elif-else 結(jié)構(gòu),代碼將不能正確地運(yùn)行,因?yàn)橛幸粋€(gè)測(cè)試通過(guò)后,就會(huì)跳過(guò)余下的測(cè)試:
1 requested_toppings = ['mushrooms', 'extra cheese']2 if 'mushrooms' in requested_toppings:3 print('Adding mushrooms.')4 elif 'pepperoni' in requested_toppings:5 print('Adding pepperoni.')6 elif 'extra cheese' in requested_toppings:7 print('Adding extra cheese.')8 print('\nFinished making your pizza!')
第一個(gè)測(cè)試檢查列表中是否包含 'mushrooms' ,它通過(guò)了,因此將在比薩中添加蘑菇。然而, Python 將跳過(guò) if-elif-else 結(jié)構(gòu)中余下的測(cè)試,不再檢查列表中是否包
含 'extra cheese' 和 'pepperoni' 。其結(jié)果是,將添加顧客點(diǎn)的第一種配料,但不會(huì)添加其他的配料:
總之,如果你只想執(zhí)行一個(gè)代碼塊,就使用 if-elif-else 結(jié)構(gòu);如果要運(yùn)行多個(gè)代碼塊,就使用一系列獨(dú)立的 if 語(yǔ)句。
5.4 使用 if 語(yǔ)句處理列表
5.4.1 檢查特殊元素
繼續(xù)使用前面的比薩店示例。這家比薩店在制作比薩時(shí),每添加一種配料都打印一條消息。通過(guò)創(chuàng)建一個(gè)列表,在其中包含顧客點(diǎn)的配料,并使用一個(gè)循環(huán)來(lái)指出添加到比薩中
的配料,可以以極高的效率編寫這樣的代碼:
輸出很簡(jiǎn)單,因?yàn)樯鲜龃a不過(guò)是一個(gè)簡(jiǎn)單的 for 循環(huán):
然而,如果比薩店的青椒用完了,該如何處理呢?為妥善地處理這種情況,可在 for 循環(huán)中包含一條 if 語(yǔ)句:
1 requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']2 for requested_topping in requested_toppings:3 if requested_topping == 'green peppers':4 print('Sorry, we are out of green peppers right now.')5 else:6 print('Adding ' + requested_topping + '.')7 print('\nFinished making your pizza!')
5.4.2 確定列表不是空的
在運(yùn)行 for 循環(huán)前確定列表是否為空很重要。
下面在制作比薩前檢查顧客點(diǎn)的配料列表是否為空。如果列表是空的,就向顧客確認(rèn)他是否要點(diǎn)普通比薩;如果列表不為空,就像前面的示例那樣制作比薩:
5.4.3 使用多個(gè)列表
顧客的要求往往五花八門,在比薩配料方面尤其如此。如果顧客要在比薩中添加炸薯?xiàng)l,該怎么辦呢?可使用列表和 if 語(yǔ)句來(lái)確定能否滿足顧客的要求。
來(lái)看看在制作比薩前如何拒絕怪異的配料要求。下面的示例定義了兩個(gè)列表,其中第一個(gè)列表包含比薩店供應(yīng)的配料,而第二個(gè)列表包含顧客點(diǎn)的配料。這次對(duì)
于 requested_toppings 中的每個(gè)元素,都檢查它是否是比薩店供應(yīng)的配料,再?zèng)Q定是否在比薩中添加它:
1 available_toppings = ['mushrooms', 'olives', 'green peppers',2 'pepperoni', 'pineapple', 'extra cheese']3 requested_toppings = ['mushrooms', 'french fries', 'extra cheese']4 for requested_topping in requested_toppings:5 if requested_topping in available_toppings:6 print('Adding ' + requested_topping + '.')7 else:8 print('Sorry, we don't have ' + requested_topping + '.')9 print('\nFinished making your pizza!')
5.5 設(shè)置 if 語(yǔ)句的格式
本章的每個(gè)示例都展示了良好的格式設(shè)置習(xí)慣。在條件測(cè)試的格式設(shè)置方面, PEP 8 提供的唯一建議是,在諸如 == 、 >= 和 <= 等比較運(yùn)算符兩邊各添加一個(gè)空格,例如, if
age < 4: 要比 if age<4: 好。
這樣的空格不會(huì)影響 Python 對(duì)代碼的解讀,而只是讓代碼閱讀起來(lái)更容易。
第 6 章 字典
理解字典后,你就能夠更準(zhǔn)確地為各種真實(shí)物體建模。你可以創(chuàng)建一個(gè)表示人的字典,然后想在其中存儲(chǔ)多少信息就存儲(chǔ)多少信息:姓名、年齡、地址、職業(yè)以及要描述的任何方面。你還能夠存儲(chǔ)任意兩種相關(guān)的信息,如一系列單詞及其含義,一系列人名及其喜歡的數(shù)字,以及一系列山脈及其海拔等。
6.1 一個(gè)簡(jiǎn)單的字典
來(lái)看一個(gè)游戲,其中包含一些外星人,這些外星人的顏色和點(diǎn)數(shù)各不相同。下面是一個(gè)簡(jiǎn)單的字典,存儲(chǔ)了有關(guān)特定外星人的信息:
字典 alien_0 存儲(chǔ)了外星人的顏色和點(diǎn)數(shù)。使用兩條 print 語(yǔ)句來(lái)訪問(wèn)并打印這些信息,如下所示:
green5
與大多數(shù)編程概念一樣,要熟練使用字典,也需要一段時(shí)間的練習(xí)。使用字典一段時(shí)間后,你就會(huì)明白為何它們能夠高效地模擬現(xiàn)實(shí)世界中的情形。
6.2 使用字典
在 Python 中, 字典 是一系列 鍵 — 值對(duì) 。每個(gè) 鍵 都與一個(gè)值相關(guān)聯(lián),你可以使用鍵來(lái)訪問(wèn)與之相關(guān)聯(lián)的值。與鍵相關(guān)聯(lián)的值可以是數(shù)字、字符串、列表乃至字典。事實(shí)上,可將
任何 Python 對(duì)象用作字典中的值。
在 Python 中,字典用放在花括號(hào) {} 中的一系列鍵 — 值對(duì)表示。
鍵 — 值 對(duì)是兩個(gè)相關(guān)聯(lián)的值。指定鍵時(shí), Python 將返回與之相關(guān)聯(lián)的值。鍵和值之間用冒號(hào)分隔,而鍵 — 值對(duì)之間用逗號(hào)分隔。在字典中,你想存儲(chǔ)多少個(gè)鍵 — 值對(duì)都可以。
最簡(jiǎn)單的字典只有一個(gè)鍵 — 值對(duì),如下述修改后的字典 alien_0 所示:
這個(gè)字典只存儲(chǔ)了一項(xiàng)有關(guān) alien_0 的信息,具體地說(shuō)是這個(gè)外星人的顏色。在這個(gè)字典中,字符串 'color' 是一個(gè)鍵,與之相關(guān)聯(lián)的值為 'green' 。
6.2.1 訪問(wèn)字典中的值
要獲取與鍵相關(guān)聯(lián)的值,可依次指定字典名和放在方括號(hào)內(nèi)的鍵,如下所示:
1 alien_0 = {'color': 'green'}2 print(alien_0['color'])
這將返回字典 alien_0 中與鍵 'color' 相關(guān)聯(lián)的值:
字典中可包含任意數(shù)量的鍵 — 值對(duì)。
如果玩家射殺了這個(gè)外星人,你就可以使用下面的代碼來(lái)確定玩家應(yīng)獲得多少個(gè)點(diǎn):
1 aliens_0={'color':'green','points':5}2 new_points=aliens_0['points']3 print('You just earned '+str(new_points)+' points.')
上述代碼首先定義了一個(gè)字典,然后從這個(gè)字典中獲取與鍵 'points' 相關(guān)聯(lián)的值(見(jiàn)?),并將這個(gè)值存儲(chǔ)在變量 new_points 中。接下來(lái),將這個(gè)整數(shù)轉(zhuǎn)換為字符串,并打印一條消息,指出玩家獲得了多少個(gè)點(diǎn)(見(jiàn)?):
6.2.2 添加鍵 — 值對(duì)
字典是一種動(dòng)態(tài)結(jié)構(gòu),可隨時(shí)在其中添加鍵 — 值對(duì)。要添加鍵 — 值對(duì),可依次指定字典名、用方括號(hào)括起的鍵和相關(guān)聯(lián)的值。
下面在字典 alien_0 中添加兩項(xiàng)信息:外星人的 x 坐標(biāo)和 y 坐標(biāo),讓我們能夠在屏幕的特定位置顯示該外星人。我們將這個(gè)外星人放在屏幕左邊緣,且離屏幕上邊緣 25 像素的地
方。由于屏幕坐標(biāo)系的原點(diǎn)通常為左上角,因此要將該外星人放在屏幕左邊緣,可將 x 坐標(biāo)設(shè)置為 0 ;要將該外星人放在離屏幕頂部 25 像素的地方,可將 y 坐標(biāo)設(shè)置為 25 ,如下所
示:
1 aliens_0={'color':'green','points':5}2 print(aliens_0)3 4 aliens_0['x_position']=05 aliens_0['y_position']=256 print(aliens_0)
我們首先定義了前面一直在使用的字典,然后打印這個(gè)字典,以顯示其信息快照。在?處,我們?cè)谶@個(gè)字典中新增了一個(gè)鍵 — 值對(duì),其中的鍵為 'x_position' ,而值為 0 。在
?處,我們重復(fù)這樣的操作,但使用的鍵為 'y_position' 。打印修改后的字典時(shí),將看到這兩個(gè)新增的鍵 — 值對(duì):
注意,鍵 — 值對(duì)的排列順序與添加順序不同。 Python 不關(guān)心鍵 — 值對(duì)的添加順序,而只關(guān)心鍵和值之間的關(guān)聯(lián)關(guān)系。
6.2.3 先創(chuàng)建一個(gè)空字典
有時(shí)候,在空字典中添加鍵 — 值對(duì)是為了方便,而有時(shí)候必須這樣做。為此,可先使用一對(duì)空的花括號(hào)定義一個(gè)字典,再分行添加各個(gè)鍵 — 值對(duì)。
使用字典來(lái)存儲(chǔ)用戶提供的數(shù)據(jù)或在編寫能自動(dòng)生成大量鍵 — 值對(duì)的代碼時(shí),通常都需要先定義一個(gè)空字典。
6.2.4 修改字典中的值
要修改字典中的值,可依次指定字典名、用方括號(hào)括起的鍵以及與該鍵相關(guān)聯(lián)的新值。例如,假設(shè)隨著游戲的進(jìn)行,需要將一個(gè)外星人從綠色改為黃色:
aliens_0={'color':'green'}print('The alien is '+aliens_0['color']+'.')aliens_0['color']='yellow'print('The alien is now '+aliens_0['color']+'.')
輸出:
來(lái)看一個(gè)更有趣的例子:對(duì)一個(gè)能夠以不同速度移動(dòng)的外星人的位置進(jìn)行跟蹤。為此,我們將存儲(chǔ)該外星人的當(dāng)前速度,并據(jù)此確定該外星人將向右移動(dòng)多遠(yuǎn):
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}print('Original x-position: ' + str(alien_0['x_position']))# 向右移動(dòng)外星人# 據(jù)外星人當(dāng)前速度決定將其移動(dòng)多遠(yuǎn)if alien_0['speed'] == 'slow': x_increment = 1elif alien_0['speed'] == 'medium': x_increment = 2else:# 這個(gè)外星人的速度一定很快 x_increment = 3# 新位置等于老位置加上增量alien_0['x_position'] = alien_0['x_position'] + x_incrementprint('New x-position: ' + str(alien_0['x_position']))
由于這是一個(gè)速度中等的外星人,因此其位置將向右移動(dòng)兩個(gè)單位:
這種技術(shù)很棒:通過(guò)修改外星人字典中的值,可改變外星人的行為。例如,要將這個(gè)速度中等的外星人變成速度很快的外星人,可添加如下代碼行:
alien_0['speed'] = 'fast'
這樣,再次運(yùn)行這些代碼時(shí),其中的 if-elif-else 結(jié)構(gòu)將把一個(gè)更大的值賦給變量 x_increment 。
6.2.5 刪除鍵 — 值對(duì)
對(duì)于字典中不再需要的信息,可使用 del 語(yǔ)句將相應(yīng)的鍵 — 值對(duì)徹底刪除。使用 del 語(yǔ)句時(shí),必須指定字典名和要?jiǎng)h除的鍵。
例如,下面的代碼從字典 alien_0 中刪除鍵 'points' 及其值:
?處的代碼行讓 Python 將鍵 'points' 從字典 alien_0 中刪除,同時(shí)刪除與這個(gè)鍵相關(guān)聯(lián)的值。輸出表明,鍵 'points' 及其值 5 已從字典中刪除,但其他鍵 — 值對(duì)未受影響:
{'points': 5, 'color': 'green'}{'color': 'green'}
注意:刪除的鍵 — 值對(duì)永遠(yuǎn)消失了。
6.2.6 由類似對(duì)象組成的字典
在前面的示例中,字典存儲(chǔ)的是一個(gè)對(duì)象(游戲中的一個(gè)外星人)的多種信息,但你也可以使用字典來(lái)存儲(chǔ)眾多對(duì)象的同一種信息。例如,假設(shè)你要調(diào)查很多人,詢問(wèn)他們最喜歡的編程語(yǔ)言,可使用一個(gè)字典來(lái)存儲(chǔ)這種簡(jiǎn)單調(diào)查的結(jié)果,如下所示:
正如你看到的,我們將一個(gè)較大的字典放在了多行中。其中每個(gè)鍵都是一個(gè)被調(diào)查者的名字,而每個(gè)值都是被調(diào)查者喜歡的語(yǔ)言。確定需要使用多行來(lái)定義字典時(shí),在輸入左花
括號(hào)后按回車鍵,再在下一行縮進(jìn)四個(gè)空格,指定第一個(gè)鍵 — 值對(duì),并在它后面加上一個(gè)逗號(hào)。此后你再次按回車鍵時(shí),文本編輯器將自動(dòng)縮進(jìn)后續(xù)鍵 — 值對(duì),且縮進(jìn)量與第一
個(gè)鍵 — 值對(duì)相同。
定義好字典后,在最后一個(gè)鍵 — 值對(duì)的下一行添加一個(gè)右花括號(hào),并縮進(jìn)四個(gè)空格,使其與字典中的鍵對(duì)齊。另外一種不錯(cuò)的做法是在最后一個(gè)鍵 — 值對(duì)后面也加上逗號(hào),為以
后在下一行添加鍵 — 值對(duì)做好準(zhǔn)備。
(這個(gè)編程細(xì)節(jié)設(shè)計(jì)的說(shuō)明很用心了)
注意 對(duì)于較長(zhǎng)的列表和字典,大多數(shù)編輯器都有以類似方式設(shè)置其格式的功能。對(duì)于較長(zhǎng)的字典,還有其他一些可行的格式設(shè)置方式,因此在你的編輯器或其他源代碼中,你可能會(huì)看到稍微不同的格式設(shè)置方式。
給定被調(diào)查者的名字,可使用這個(gè)字典輕松地獲悉他喜歡的語(yǔ)言:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}print('Sarah's favorite language is ' +favorite_languages['sarah'].title()
+'.')
這個(gè)示例還演示了如何將較長(zhǎng)的 print 語(yǔ)句分成多行。單詞 print 比大多數(shù)字典名都短,因此讓輸出的第一部分緊跟在左括號(hào)后面是合理的。請(qǐng)選擇在合適的地方拆
分要打印的內(nèi)容,并在第一行末尾加上一個(gè)拼接運(yùn)算符( + )。按回車鍵進(jìn)入 print 語(yǔ)句的后續(xù)各行,并使用 Tab 鍵將它們對(duì)齊并縮進(jìn)一級(jí)。指定要打印的所有內(nèi)容
后,在 print 語(yǔ)句的最后一行末尾加上右括號(hào)。
6.3 遍歷字典
一個(gè) Python 字典可能只包含幾個(gè)鍵 — 值對(duì),也可能包含數(shù)百萬(wàn)個(gè)鍵 — 值對(duì)。鑒于字典可能包含大量的數(shù)據(jù), Python 支持對(duì)字典遍歷。字典可用于以各種方式存儲(chǔ)信息,因此有多種
遍歷字典的方式:可遍歷字典的所有鍵 — 值對(duì)、鍵或值。
6.3.1 遍歷所有的鍵 — 值對(duì)
探索各種遍歷方法前,先來(lái)看一個(gè)新字典,它用于存儲(chǔ)有關(guān)網(wǎng)站用戶的信息。下面的字典存儲(chǔ)一名用戶的用戶名、名和姓:
利用本章前面介紹過(guò)的知識(shí),可訪問(wèn) user_0 的任何一項(xiàng)信息,但如果要獲悉該用戶字典中的所有信息,該怎么辦呢?可以使用一個(gè) for 循環(huán)來(lái)遍歷這個(gè)字典:
user_0 = {'username': 'efermi','first': 'enrico','last': 'fermi',}for key, value in user_0.items(): print('\nKey: ' + key) print('Value: ' + value)
for 語(yǔ)句的第二部分包含字典名和方法 items() ,它返回一個(gè)鍵 — 值對(duì)列表。接下來(lái), for 循環(huán)依次將每個(gè)鍵 — 值對(duì)存儲(chǔ)到指定的兩個(gè)變量中。在前面的示例中,我
們使用這兩個(gè)變量來(lái)打印每個(gè)鍵及其相關(guān)聯(lián)的值。第一條 print 語(yǔ)句中的 '\n' 確保在輸出每個(gè)鍵 — 值對(duì)前都插入一個(gè)空行:
注意,即便遍歷字典時(shí),鍵 — 值對(duì)的返回順序也與存儲(chǔ)順序不同。 Python 不關(guān)心鍵 — 值對(duì)的存儲(chǔ)順序,而只跟蹤鍵和值之間的關(guān)聯(lián)關(guān)系。
在 6.2.6 節(jié)的示例 favorite_languages.py 中,字典存儲(chǔ)的是不同人的同一種信息;對(duì)于類似這樣的字典,遍歷所有的鍵 — 值對(duì)很合適。如果遍歷字典 favorite_languages ,將得到
其中每個(gè)人的姓名和喜歡的編程語(yǔ)言。由于其中的鍵都是人名,而值都是語(yǔ)言,因此我們?cè)谘h(huán)中使用變量 name 和 language ,而不是 key 和 value ,這讓人更容易明白循環(huán)
的作用:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}for name, language in favorite_languages.items(): print(name.title() + ''s favorite language is ' + language.title() + '.')
僅使用幾行代碼,我們就將全部調(diào)查結(jié)果顯示出來(lái)了:
即便字典存儲(chǔ)的是上千乃至上百萬(wàn)人的調(diào)查結(jié)果,這種循環(huán)也管用。
6.3.2 遍歷字典中的所有鍵
在不需要使用字典中的值時(shí),方法 keys() 很有用。下面來(lái)遍歷字典 favorite_languages ,并將每個(gè)被調(diào)查者的名字都打印出來(lái):
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}for name in favorite_languages.keys(): print(name.title())
Python 提取字典 favorite_languages 中的所有鍵,并依次將它們存儲(chǔ)到變量 name 中。輸出列出了每個(gè)被調(diào)查者的名字:
遍歷字典時(shí),會(huì)默認(rèn)遍歷所有的鍵,因此,如果將上述代碼中的 for name in favorite_languages.keys(): 替換為 for name in favorite_languages: ,輸出將不變。
如果顯式地使用方法 keys() 可讓代碼更容易理解,你可以選擇這樣做,但如果你愿意,也可省略它。
在這種循環(huán)中,可使用當(dāng)前鍵來(lái)訪問(wèn)與之相關(guān)聯(lián)的值。下面來(lái)打印兩條消息,指出兩位朋友喜歡的語(yǔ)言。我們像前面一樣遍歷字典中的名字,但在名字為指定朋友的名字時(shí),打印一條消息,指出其喜歡的語(yǔ)言:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}friends=['phil','sarah']for name in favorite_languages: print(name.title()) if name in friends: print(' Hi ' + name.title() + ', I see your favorite language is ' + favorite_languages[name].title() + '!')
我們創(chuàng)建了一個(gè)列表,其中包含我們要通過(guò)打印消息,指出其喜歡的語(yǔ)言的朋友。在循環(huán)中,我們打印每個(gè)人的名字,并檢查當(dāng)前的名字是否在列表 friends 中。如果在列表中,就打印一句特殊的問(wèn)候語(yǔ),其中包含這位朋友喜歡的語(yǔ)言。為訪問(wèn)喜歡的語(yǔ)言,我們使用了字典名,并將變量 name 的當(dāng)前值作為鍵。每個(gè)人的名字都會(huì)被打印,但只對(duì)朋友打印特殊消息:
你還可以使用 keys() 確定某個(gè)人是否接受了調(diào)查。下面的代碼確定 Erin 是否接受了調(diào)查:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}if 'erin' not in favorite_languages.keys(): print('Erin, please take our poll!')
方法 keys() 并非只能用于遍歷;實(shí)際上,它返回一個(gè)列表,其中包含字典中的所有鍵,因此代碼行只是核實(shí) 'erin' 是否包含在這個(gè)列表中。由于她并不包含在這個(gè)列表中,因此打印一條消息,邀請(qǐng)她參加調(diào)查:
6.3.3 按順序遍歷字典中的所有鍵
字典總是明確地記錄鍵和值之間的關(guān)聯(lián)關(guān)系,但獲取字典的元素時(shí),獲取順序是不可預(yù)測(cè)的。這不是問(wèn)題,因?yàn)橥ǔD阆胍闹皇谦@取與鍵相關(guān)聯(lián)的正確的值。
要以特定的順序返回元素,一種辦法是在 for 循環(huán)中對(duì)返回的鍵進(jìn)行排序。為此,可使用函數(shù) sorted() 來(lái)獲得按特定順序排列的鍵列表的副本:
favorite_languages = { 'jen': 'python', 'sarah': 'c', 'edward': 'ruby', 'phil': 'python', }for name in sorted(favorite_languages.keys()): print(name.title() + ', thank you for taking the poll.')
這條 for 語(yǔ)句類似于其他 for 語(yǔ)句,但對(duì)方法 dictionary.keys() 的結(jié)果調(diào)用了函數(shù) sorted() 。這讓 Python 列出字典中的所有鍵,并在遍歷前對(duì)這個(gè)列表進(jìn)行排序(按照首字母大小寫)。輸出
表明,按順序顯示了所有被調(diào)查者的名字:
6.3.4 遍歷字典中的所有值
如果你感興趣的主要是字典包含的值,可使用方法 values() ,它返回一個(gè)值列表,而不包含任何鍵。例如,如果我們想獲得一個(gè)這樣的列表,即其中只包含被調(diào)查者選擇的各
種語(yǔ)言,而不包含被調(diào)查者的名字,可以這樣做:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}print('The following languages have been mentioned:')for language in favorite_languages.values():print(language.title())
這條 for 語(yǔ)句提取字典中的每個(gè)值,并將它們依次存儲(chǔ)到變量 language 中。通過(guò)打印這些值,就獲得了一個(gè)列表,其中包含被調(diào)查者選擇的各種語(yǔ)言:
這種做法提取字典中所有的值,而沒(méi)有考慮是否重復(fù)。涉及的值很少時(shí),這也許不是問(wèn)題,但如果被調(diào)查者很多,最終的列表可能包含大量的重復(fù)項(xiàng)。為剔除重復(fù)項(xiàng),可使用集合( set )。 集合 類似于列表,但每個(gè)元素都必須是獨(dú)一無(wú)二的:
favorite_languages = {'jen': 'python','sarah': 'c','edward': 'ruby','phil': 'python',}print('The following languages have been mentioned:')for language in set(favorite_languages.values()): print(language.title())
通過(guò)對(duì)包含重復(fù)元素的列表調(diào)用 set() ,可讓 Python 找出列表中獨(dú)一無(wú)二的元素,并使用這些元素來(lái)創(chuàng)建一個(gè)集合。在?處,我們使用了 set() 來(lái)提
取 favorite_languages.values() 中不同的語(yǔ)言。
結(jié)果是一個(gè)不重復(fù)的列表,其中列出了被調(diào)查者提及的所有語(yǔ)言:
隨著你更深入地學(xué)習(xí) Python ,經(jīng)常會(huì)發(fā)現(xiàn)它內(nèi)置的功能可幫助你以希望的方式處理數(shù)據(jù)。
聯(lián)系客服