Python書籍閱讀與記錄 6.12 I

我感覺這樣記錄,對於我來說挺好的。因爲我看兩端對齊的語句容易走神,這樣記錄閱讀的話,就很少出現之前的情況。

我寫的初衷,也是自己來看,所以感覺寫的不好的,請保留下意見,謝謝。

 

裏面的每一個字我都看過,加粗 括號  下劃線 等均是我的筆記。

 

第6章 字典
 
在本章中,你將學習能夠將相關信息關聯起來的Python字典。你將學習如何訪問和修改字典中的信息。鑑於字典可存儲的信息量幾乎不受限制,因此我們會演示如何遍
歷字典中的數據。另外,你還將學習存儲字典的列表、存儲列表的字典和存儲字典的字典。
理解字典後,你就能夠更準確地爲各種真實物體建模。你可以創建一個表示人的字典,然後想在其中存儲多少信息就存儲多少信息:姓名、年齡、地址、職業以及要
描述的任何方面。你還能夠存儲任意兩種相關的信息,如一系列單詞及其含義,一系列人名及其喜歡的數字,以及一系列山脈及其海拔等。
6.1 一個簡單的字典(我咋感覺字典這麼像C裏面的結構體)
來看一個遊戲,其中包含一些外星人,這些外星人的顏色和點數各不相同。下面是一個簡單的字典,存儲了有關特定外星人的信息:
alien.py
alien_0 = {'color': 'green', 'points': 5}
print(alien_0['color'])
print(alien_0['points'])
字典alien_0 存儲了外星人的顏色和點數。使用兩條print 語句來訪問並打印這些信息,如下所示:
green
5
與大多數編程概念一樣,要熟練使用字典,也需要一段時間的練習。使用字典一段時間後,你就會明白爲何它們能夠高效地模擬現實世界中的情形。
6.2 使用字典
Python中,字
典 是一系列鍵——每個鍵
都與一個值相關聯你可以使用鍵來訪問與之相關聯的值與鍵相關聯的值可以是數字、字符串、列表乃至字典。事實上,可將
任何Python對象用作字典中的值。
Python中,字典用放在花括號{} 中的一系列鍵—值對錶示,如前面的示例所示:
alien_0 = {'color': 'green', 'points': 5}
對是兩個相關聯的值。指定鍵時,Python將返回與之相關聯的值。鍵和值之間用冒號分隔,而鍵—值對之間用逗號分隔。在字典中,你想存儲多少個鍵值對都可以。
最簡單的字典只有一個鍵值對,如下述修改後的字典alien_0 所示:
alien_0 = {'color': 'green'}
這個字典只存儲了一項有關alien_0 的信息,具體地說是這個外星人的顏色。在這個字典中,字符串'color' 是一個鍵,與之相關聯的值爲'green'
6.2.1 訪問字典中的值
要獲取與鍵相關聯的值,可依次指定字典名和放在方括號內的鍵,如下所示:alien_0 = {'color': 'green'}
print(alien_0['color'])
這將返回字典alien_0 中與鍵'color' 相關聯的值:
green
字典中可包含任意數量的鍵值對。例如,下面是最初的字典alien_0 ,其中包含兩個鍵值對:
alien_0 = {'color': 'green', 'points': 5}
現在,你可以訪問外星人alien_0 的顏色和點數。如果玩家射殺了這個外星人,你就可以使用下面的代碼來確定玩家應獲得多少個點:
alien_0 = {'color': 'green', 'points': 5}
new_points = alien_0['points']
print("You just earned " + str(new_points) + " points!")
上述代碼首先定義了一個字典,然後從這個字典中獲取與鍵'points' 相關聯的值(見),並將這個值存儲在變量new_points 中。接下來,將這個整數轉換爲字符串,並
打印一條消息,指出玩家獲得了多少個點(見):
You just earned 5 points!
如果你在有外星人被射殺時都運行這段代碼,就會獲取該外星人的點數。
6.2.2 添加鍵——值對
字典是一種動態結構,可隨時在其中添加鍵值對。要添加鍵值對,可依次指定字典名、用方括號括起的鍵和相關聯的值。
下面在字典alien_0 中添加兩項信息:外星人的 x 座標和 y 座標,讓我們能夠在屏幕的特定位置顯示該外星人。我們將這個外星人放在屏幕左邊緣,且離屏幕上邊緣25像素的地
方。由於屏幕座標系的原點通常爲左上角因此要將該外星人放在屏幕左邊緣,可將 x 座標設置爲0;要將該外星人放在離屏幕頂部25像素的地方,可將 y 座標設置爲25如下所
示:
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
alien_0['x_position'] = 0
alien_0['y_position'] = 25
print(alien_0)
我們首先定義了前面一直在使用的字典,然後打印這個字典,以顯示其信息快照。在處,我們在這個字典中新增了一個鍵值對,其中的鍵爲'x_position' ,而值爲0 。在
處,我們重複這樣的操作,但使用的鍵爲'y_position' 。打印修改後的字典時,將看到這兩個新增的鍵值對:
{'color': 'green', 'points': 5}
{'color': 'green', 'points': 5, 'y_position': 25, 'x_position': 0}
這個字典的最終版本包含四個鍵值對,其中原來的兩個指定外星人的顏色和點數,而新增的兩個指定位置。注意,鍵—值對的排列順序與添加順序不同。Python不關心鍵—值對
的添加順序,而只關心鍵和值之間的關聯關係。
6.2.3 先創建一個空字典
有時候,在空字典中添加鍵值對是爲了方便,而有時候必須這樣做。爲此,可先使用一對空的花括號定義一個字典,再分行添加各個鍵值對。例如,下例演示瞭如何以這種
方式創建字典alien_0
alien_0 = {}
alien_0['color'] = 'green'
alien_0['points'] = 5
print(alien_0)
這裏首先定義了空字典alien_0 ,再在其中添加顏色和點數,得到前述示例一直在使用的字典:
{'color': 'green', 'points': 5}
使用字典來存儲用戶提供的數據或在編寫能自動生成大量鍵值對的代碼時,通常都需要先定義一個空字典。
6.2.4 修改字典中的值
要修改字典中的值,可依次指定字典名、用方括號括起的鍵以及與該鍵相關聯的新值。例如,假設隨着遊戲的進行,需要將一個外星人從綠色改爲黃色:alien_0 = {'color': 'green'}
print("The alien is " + alien_0['color'] + ".")
alien_0['color'] = 'yellow'
print("The alien is now " + alien_0['color'] + ".")
我們首先定義了一個表示外星人alien_0 的字典,其中只包含這個外星人的顏色。接下來,我們將與鍵'color' 相關聯的值改爲'yellow' 。輸出表明,這個外星人確實從綠
色變成了黃色:
The alien is green.
The alien is now yellow.
來看一個更有趣的例子:對一個能夠以不同速度移動的外星人的位置進行跟蹤。爲此,我們將存儲該外星人的當前速度,並據此確定該外星人將向右移動多遠:
alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'}
print("Original x-position: " + str(alien_0['x_position']))
# 向右移動外星人
# 據外星人當前速度決定將其移動多遠
if alien_0['speed'] == 'slow':
x_increment = 1
elif alien_0['speed'] == 'medium':
x_increment = 2
else:
# 這個外星人的速度一定很快
x_increment = 3
# 新位置等於老位置加上增量
alien_0['x_position'] = alien_0['x_position'] + x_increment
print("New x-position: " + str(alien_0['x_position']))
我們首先定義了一個外星人,其中包含初始的x 座標和y 座標,還有速度'medium' 。出於簡化考慮,我們省略了顏色和點數,但即便包含這些鍵-值對,這個示例的工作原理也
不會有任何變化。我們還打印了x_position 的初始值,旨在讓用戶知道這個外星人向右移動了多遠。
處,使用了一個if-elif-else 結構來確定外星人應向右移動多遠,並將這個值存儲在變量x_increment 中。如果外星人的速度爲'slow' ,它將向右移動一個單位;
如果速度爲'medium' ,將向右移動兩個單位;如果爲'fast' ,將向右移動三個單位。確定移動量後,將其與x_position 的當前值相加(見),再將結果關聯到字典中
的鍵x_position
由於這是一個速度中等的外星人,因此其位置將向右移動兩個單位:
Original x-position: 0
New x-position: 2
這種技術很棒:通過修改外星人字典中的值,可改變外星人的行爲。例如,要將這個速度中等的外星人變成速度很快的外星人,可添加如下代碼行:
alien_0['speed'] = fast
這樣,再次運行這些代碼時,其中的if-elif-else 結構將把一個更大的值賦給變量x_increment
6.2.5 刪除鍵——值對
對於字典中不再需要的信息,可使用del 語句將相應的鍵值對徹底刪除。使用del 語句時,必須指定字典名和要刪除的鍵。
例如,下面的代碼從字典alien_0 中刪除鍵'points' 及其值:
alien_0 = {'color': 'green', 'points': 5}
print(alien_0)
del alien_0['points']
print(alien_0)
處的代碼行讓Python將鍵'points' 從字典alien_0 中刪除,同時刪除與這個鍵相關聯的值。輸出表明,鍵'points' 及其值5 已從字典中刪除,但其他鍵值對未受影響:
{'color': 'green', 'points': 5}
{'color': 'green'} 
注意 刪除的鍵值對永遠消失了。
6.2.6 有類似對象組成的字典
在前面的示例中,字典存儲的是一個對象(遊戲中的一個外星人)的多種信息,但你也可以使用字典來存儲衆多對象的同一種信息。例如,假設你要調查很多人,詢問他們最喜
歡的編程語言,可使用一個字典來存儲這種簡單調查的結果,如下所示:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}正如你看到的,我們將一個較大的字典放在了多行中。其中每個鍵都是一個被調查者的名字,而每個值都是被調查者喜歡的語言。確定需要使用多行來定義字典時,在輸入左花
括號後按回車鍵,再在下一行縮進四個空格,指定第一個鍵值對,並在它後面加上一個逗號。此後你再次按回車鍵時,文本編輯器將自動縮進後續鍵值對,且縮進量與第一
個鍵值對相同。
定義好字典後,在最後一個鍵值對的下一行添加一個右花括號,並縮進四個空格,使其與字典中的鍵對齊。另外一種不錯的做法是在最後一個鍵值對後面也加上逗號,爲以
後在下一行添加鍵值對做好準備。
對於較長的列表和字典,大多數編輯器都有以類似方式設置其格式的功能。對於較長的字典,還有其他一些可行的格式設置方式,因此在你的編輯器或其他源
代碼中,你可能會看到稍微不同的格式設置方式。
給定被調查者的名字,可使用這個字典輕鬆地獲悉他喜歡的語言:
favorite_languages.py
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
print("Sarah's favorite language is " +
favorite_languages['sarah'].title() +
".")
爲獲悉Sarah 喜歡的語言,我們使用如下代碼:
favorite_languages['sarah']
print 語句中,我們使用了這種語法(見);輸出指出了Sarah喜歡的語言:
Sarah's favorite language is C.
這個示例還演示瞭如何將較長的print 語句分成多行。單詞print 比大多數字典名都短,因此讓輸出的第一部分緊跟在左括號後面是合理的(見)。請選擇在合適的地方拆
分要打印的內容,並在第一行末尾(見❷)加上一個拼接運算符(+ )。按回車鍵進入print 語句的後續各行,並使用Tab鍵將它們對齊並縮進一級。指定要打印的所有內容
後,在print 語句的最後一行末尾加上右括號(見)。
動手試一試
 
6-1
:使用一個字典來存儲一個熟人的信息,包括名、姓、年齡和居住的城市。該字典應包含鍵first_name last_name age city 。將存儲在該字典中
的每項信息都打印出來。
6-2
歡的
字 :使用一個字典來存儲一些人喜歡的數字。請想出5個人的名字,並將這些名字用作字典中的鍵;想出每個人喜歡的一個數字,並將這些數字作爲值存
儲在字典中。打印每個人的名字和喜歡的數字。爲讓這個程序更有趣,通過詢問朋友確保數據是真實的。
6-3
匯表
Python字典可用於模擬現實生活中的字典,但爲避免混淆,我們將後者稱爲詞彙表。
想出你在前面學過的5個編程詞彙,將它們用作詞彙表中的鍵,並將它們的含義作爲值存儲在詞彙表中。
以整潔的方式打印每個詞彙及其含義。爲此,你可以先打印詞彙,在它後面加上一個冒號,再打印詞彙的含義;也可在一行打印詞彙,再使用換行符(\n )插
入一個空行,然後在下一行以縮進的方式打印詞彙的含義。
6.3 遍歷字典 
一個Python字典可能只包含幾個鍵值對,也可能包含數百萬個鍵值對。鑑於字典可能包含大量的數據,Python支持對字典遍歷。字典可用於以各種方式存儲信息,因此有多種
遍歷字典的方式:可遍歷字典的所有鍵值對、鍵或值。
6.3.1 遍歷所有的鍵——值對
探索各種遍歷方法前,先來看一個新字典,它用於存儲有關網站用戶的信息。下面的字典存儲一名用戶的用戶名、名和姓:
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
利用本章前面介紹過的知識,可訪問user_0 的任何一項信息,但如果要獲悉該用戶字典中的所有信息,該怎麼辦呢?可以使用一個for 循環來遍歷這個字典:
user.py
user_0 = {
'username': 'efermi',
'first': 'enrico',
'last': 'fermi',
}
for key, value in user_0.items():
print("\nKey: " + key)
print("Value: " + value)
所示,要編寫用於遍歷字典的for 循環,可聲明兩個變量,用於存儲鍵值對中的鍵和值。對於這兩個變量,可使用任何名稱。下面的代碼使用了簡單的變量名,這完全可行:
for k, v in user_0.items()
for 語句的第二部分包含字典名和方法items() (見❶),它返回一個鍵—值對列表。接下來,for 循環依次將每個鍵值對存儲到指定的兩個變量中。在前面的示例中,我
們使用這兩個變量來打印每個鍵(見)及其相關聯的值(見)。第一條print 語句中的"\n" 確保在輸出每個鍵值對前都插入一個空行:
Key: last
Value: fermi
 
Key: first
Value: enrico
 
Key: username
Value: efermi
注意,即便遍歷字典時,鍵—值對的返回順序也與存儲順序不同。Python不關心鍵—值對的存儲順序,而只跟蹤鍵和值之間的關聯關係。
6.2.6節的示例favorite_languages.py中,字典存儲的是不同人的同一種信息;對於類似這樣的字典,遍歷所有的鍵值對很合適。如果遍歷字典favorite_languages ,將得到
其中每個人的姓名和喜歡的編程語言。由於其中的鍵都是人名,而值都是語言,因此我們在循環中使用變量name language ,而不是key value ,這讓人更容易明白循環
的作用:
favorite_languages.py
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() + ".")
處的代碼讓Python遍歷字典中的每個鍵值對,並將鍵存儲在變量name 中,而將值存儲在變量language 中。這些描述性名稱能夠讓人非常輕鬆地明白print 語句(見
是做什麼的。
僅使用幾行代碼,我們就將全部調查結果顯示出來了:
Jen's favorite language is Python.
Sarah's favorite language is C.
Phil's favorite language is Python.
Edward's favorite language is Ruby.
即便字典存儲的是上千乃至上百萬人的調查結果,這種循環也管用。
6.3.2 遍歷字典中的所有鍵
在不需要使用字典中的值時,方法keys() 很有用。下面來遍歷字典favorite_languages ,並將每個被調查者的名字都打印出來:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
for name in favorite_languages.keys():
print(name.title())
處的代碼行讓Python提取字典favorite_languages 中的所有鍵,並依次將它們存儲到變量name 中。輸出列出了每個被調查者的名字:
Jen
Sarah
Phil
Edward
遍歷字典時,會默認遍歷所有的鍵,因此,如果將上述代碼中的for name in favorite_languages.keys(): 替換爲for name in favorite_languages: ,輸出
將不變。
如果顯式地使用方法keys() 可讓代碼更容易理解,你可以選擇這樣做,但如果你願意,也可省略它。
在這種循環中,可使用當前鍵來訪問與之相關聯的值。下面來打印兩條消息,指出兩位朋友喜歡的語言。我們像前面一樣遍歷字典中的名字,但在名字爲指定朋友的名字時,打
印一條消息,指出其喜歡的語言:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
friends = ['phil', 'sarah']
for name in favorite_languages.keys():print(name.title())
if name in friends:
print(" Hi " + name.title() +
", I see your favorite language is " +
favorite_languages[name].title() + "!")
在❶處,我們創建了一個列表,其中包含我們要通過打印消息,指出其喜歡的語言的朋友。在循環中,我們打印每個人的名字,並檢查當前的名字是否在列表friends 中(見
❷)。如果在列表中,就打印一句特殊的問候語,其中包含這位朋友喜歡的語言。爲訪問喜歡的語言,我們使用了字典名,並將變量name 的當前值作爲鍵(見❸)。每個人的
名字都會被打印,但只對朋友打印特殊消息:
Edward
Phil
Hi Phil, I see your favorite language is Python!
Sarah
Hi Sarah, I see your favorite language is C!
Jen 
你還可以使用keys() 確定某個人是否接受了調查。下面的代碼確定Erin是否接受了調查:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
if 'erin' not in favorite_languages.keys():
print("Erin, please take our poll!")
方法keys() 並非只能用於遍歷;實際上,它返回一個列表,其中包含字典中的所有鍵,因此處的代碼行只是覈實'erin' 是否包含在這個列表中。由於她並不包含在這個列
表中,因此打印一條消息,邀請她參加調查:
Erin, please take our poll!
6.3.3 按順序遍歷字典中的所有鍵
字典總是明確地記錄鍵和值之間的關聯關係,但獲取字典的元素時,獲取順序是不可預測的。這不是問題,因爲通常你想要的只是獲取與鍵相關聯的正確的值。
要以特定的順序返回元素,一種辦法是在for 循環中對返回的鍵進行排序。爲此,可使用函數sorted() 來獲得按特定順序排列的鍵列表的副本
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 語句類似於其他for 語句,但對方法dictionary.keys() 的結果調用了函數sorted() 。這讓Python列出字典中的所有鍵,並在遍歷前對這個列表進行排序。輸出
表明,按順序顯示了所有被調查者的名字:
Edward, thank you for taking the poll.
Jen, thank you for taking the poll.
Phil, thank you for taking the poll.
Sarah, thank you for taking the poll.
6.3.4 遍歷字典中的所有值
如果你感興趣的主要是字典包含的可使用方法values() ,它返回一個值列表,而不包含任何鍵。例如,如果我們想獲得一個這樣的列表,即其中只包含被調查者選擇的各
種語言,而不包含被調查者的名字,可以這樣做:
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 語句提取字典中的每個值,並將它們依次存儲到變量language 中。通過打印這些值,就獲得了一個列表,其中包含被調查者選擇的各種語言:
The following languages have been mentioned:
Python
C
Python
Ruby
我在下面跑的程序:  讀者們可以看看,我經驗證知道了 作者所說的返回一個列表,並不是很嚴謹,返回的是一次一個值
作者的意思應該是favorite_languages.values()這個是個列表,也就是說這個字典的values()方法,返回一個列表
相當於for 變量 in 列表 這樣子
>>> dir={'1':'one','2':'two','3':'three'}
>>> dir
{'1': 'one', '2': 'two', '3': 'three'}
>>> for di in dir.values():
...    print(di.title())
...
One
Two
Three
>>> di
'three'
>>> print(di)
three
>>>
這種做法提取字典中所有的值,而沒有考慮是否重複。涉及的值很少時,這也許不是問題,但如果被調查者很多,最終的列表可能包含大量的重複項。爲剔除重複項,可使用集
合(set)。
集合
類似於列表,但每個元素都必須是獨一無二的:
favorite_languages = {
'jen': 'python',
'sarah': 'c',
'edward': 'ruby',
'phil': 'python',
}
print("The following languages have been mentioned:")
for language in set(favorite_languages.values()):    # set  n. 集合
print(language.title())
通過對包含重複元素的列表調用set() ,可讓Python找出列表中獨一無二的元素,並使用這些元素來創建一個集合。在處,我們使用了set() 來提
favorite_languages.values() 中不同的語言。
結果是一個不重複的列表,其中列出了被調查者提及的所有語言:
The following languages have been mentioned:
Python
C
Ruby
隨着你更深入地學習Python,經常會發現它內置的功能可幫助你以希望的方式處理數據。
動手試一試
 
6-4
匯表
2 :既然你知道了如何遍歷字典,現在請整理你爲完成練習6-3而編寫的代碼,將其中的一系列print 語句替換爲一個遍歷字典中的鍵和值的循環。確定該
循環正確無誤後,再在詞彙表中添加5Python術語。當你再次運行這個程序時,這些新術語及其含義將自動包含在輸出中。
6-5
流 :創建一個字典,在其中存儲三條大河流及其流經的國家。其中一個鍵值對可能是'nile': 'egypt'
使用循環爲每條河流打印一條消息,如“The Nileruns through Egypt.”
使用循環將該字典中每條河流的名字都打印出來。
使用循環將該字典包含的每個國家的名字都打印出來。
6-6 調
查 :在6.3.1節編寫的程序favorite_languages.py中執行以下操作。
創建一個應該會接受調查的人員名單,其中有些人已包含在字典中,而其他人未包含在字典中。
遍歷這個人員名單,對於已參與調查的人,打印一條消息表示感謝。對於還未參與調查的人,打印一條消息邀請他參與調查。
6.4 嵌套
有時候,需要將一系列字典存儲在列表中,或將列表作爲值存儲在字典中,這稱爲嵌
套 。你可以在列表中嵌套字典、在字典中嵌套列表甚至在字典中嵌套字典。正如下面的示例
將演示的,嵌套是一項強大的功能。
6.4.1 字典列表
字典alien_0 包含一個外星人的各種信息,但無法存儲第二個外星人的信息,更別說屏幕上全部外星人的信息了。如何管理成羣結隊的外星人呢?一種辦法是創建一個外星人列
表,其中每個外星人都是一個字典,包含有關該外星人的各種信息。例如,下面的代碼創建一個包含三個外星人的列表:
aliens.py
alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}
aliens = [alien_0, alien_1, alien_2]
for alien in aliens:
print(alien)
我們首先創建了三個字典,其中每個字典都表示一個外星人。在處,我們將這些字典都放到一個名爲aliens 的列表中。最後,我們遍歷這個列表,並將每個外星人都打印出
來:
{'color': 'green', 'points': 5}
{'color': 'yellow', 'points': 10}
{'color': 'red', 'points': 15}
更符合現實的情形是,外星人不止三個,且每個外星人都是使用代碼自動生成的。在下面的示例中,我們使用range() 生成了30個外星人:
# 創建一個用於存儲外星人的空列表
aliens = []
# 創建30個綠色的外星人
for alien_number in range(30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
# 顯示前五個外星人
for alien in aliens[:5]:
print(alien)
print("...")# 顯示創建了多少個外星人
print("Total number of aliens: " + str(len(aliens)))
在這個示例中,首先創建了一個空列表,用於存儲接下來將創建的所有外星人。在處,range() 返回一系列數字,其唯一的用途是告訴Python我們要重複這個循環多少次。每
次執行這個循環時,都創建一個外星人(見),並將其附加到列表aliens 末尾(見)。在處,使用一個切片來打印前五個外星人;在處,打印列表的長度,以證明確
實創建了30個外星人:
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
...
Total number of aliens: 30
這些外星人都具有相同的特徵,但在Python看來,每個外星人都是獨立的,這讓我們能夠獨立地修改每個外星人。
在什麼情況下需要處理成羣結隊的外星人呢?想象一下,可能隨着遊戲的進行,有些外星人會變色且移動速度會加快。必要時,我們可以使用for 循環和if 語句來修改某些外星
人的顏色。例如,要將前三個外星人修改爲黃色的、速度爲中等且值10個點,可以這樣做:
# 創建一個用於存儲外星人的空列表
aliens = []
# 創建30個綠色的外星人
for alien_number in range (0,30):
new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
aliens.append(new_alien)
for alien in aliens[0:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10
# 顯示前五個外星人
for alien in aliens[0:5]:
print(alien)
print("...")
鑑於我們要修改前三個外星人,需要遍歷一個只包含這些外星人的切片。當前,所有外星人都是綠色的,但情況並非總是如此,因此我們編寫了一條if 語句來確保只修改綠色外
星人。如果外星人是綠色的,我們就將其顏色改爲'yellow' ,將其速度改爲'medium' ,並將其點數改爲10 ,如下面的輸出所示:
{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
...
你可以進一步擴展這個循環,在其中添加一個elif 代碼塊,將黃色外星人改爲移動速度快且值15個點的紅色外星人,如下所示(這裏只列出了循環,而沒有列出整個程序):
for alien in aliens[0:3]:
if alien['color'] == 'green':
alien['color'] = 'yellow'
alien['speed'] = 'medium'
alien['points'] = 10
elif alien['color'] == 'yellow':
alien['color'] = 'red'
alien['speed'] = 'fast'
alien['points'] = 15   (關於代碼縮進,自己領會,我就不改了)
經常需要在列表中包含大量的字典,而其中每個字典都包含特定對象的衆多信息。例如,你可能需要爲網站的每個用戶創建一個字典(就像6.3.1節的user.py中那樣),並將這些
字典存儲在一個名爲users 的列表中。在這個列表中,所有字典的結構都相同,因此你可以遍歷這個列表,並以相同的方式處理其中的每個字典。
6.4.2 在字典中存儲列表
有時候,需要將列表存儲在字典中,而不是將字典存儲在列表中。例如,你如何描述顧客點的比薩呢?如果使用列表,只能存儲要添加的比薩配料;但如果使用字典,就不僅可
在其中包含配料列表,還可包含其他有關比薩的描述。
在下面的示例中,存儲了比薩的兩方面信息:外皮類型和配料列表。其中的配料列表是一個與鍵'toppings' 相關聯的值。要訪問該列表,我們使用字典名和鍵'toppings'
,就像訪問字典中的其他值一樣。這將返回一個配料列表,而不是單個值:
pizza.py
# 存儲所點比薩的信息
pizza = {
'crust': 'thick',
'toppings': ['mushrooms', 'extra cheese'],
}
# 概述所點的比薩
print("You ordered a " + pizza['crust'] + "-crust pizza " +
"with the following toppings:")
for topping in pizza['toppings']:
print("\t" + topping)我們首先創建了一個字典,其中存儲了有關顧客所點比薩的信息(見)。在這個字典中,一個鍵是'crust' ,與之相關聯的值是字符串'thick' ;下一個鍵是'toppings'
,與之相關聯的值是一個列表,其中存儲了顧客要求添加的所有配料。製作前我們概述了顧客所點的比薩(見)。爲打印配料,我們編寫了一個for 循環(見)。爲訪問配
料列表,我們使用了鍵'toppings' ,這樣Python將從字典中提取配料列表。
下面的輸出概述了要製作的比薩:
You ordered a thick-crust pizza with the following toppings:
mushrooms
extra cheese
相當於for 變量 in 列表 這樣子 跟前面一樣
每當需要在字典中將一個鍵關聯到多個值時,都可以在字典中嵌套一個列表。在本章前面有關喜歡的編程語言的示例中,如果將每個人的回答都存儲在一個列表中,被調查者就
可選擇多種喜歡的語言。在這種情況下,當我們遍歷字典時,與每個被調查者相關聯的都是一個語言列表,而不是一種語言;因此,在遍歷該字典的for 循環中,我們需要再使
用一個for 循環來遍歷與被調查者相關聯的語言列表:
favorite_languages.py
favorite_languages = {
'jen': ['python', 'ruby'],
'sarah': ['c'],
'edward': ['ruby', 'go'],
'phil': ['python', 'haskell'],
}
for name, languages in favorite_languages.items():
print("\n" + name.title() + "'s favorite languages are:")
for language in languages:
print("\t" + language.title())
正如你看到的,現在與每個名字相關聯的值都是一個列表(見)。請注意,有些人喜歡的語言只有一種,而有些人有多種。遍歷字典時(見),我們使用了變量languages
來依次存儲字典中的每個值,因爲我們知道這些值都是列表。在遍歷字典的主循環中,我們又使用了一個for 循環來遍歷每個人喜歡的語言列表(見)。現在,每個人想列出
多少種喜歡的語言都可以:
Jen's favorite languages are:
Python
Ruby
Sarah's favorite languages are:
C
Phil's favorite languages are:
Python
Haskell
Edward's favorite languages are:
Ruby
Go
>>> for k,v in dir.items():
...   print(k,v)
...
1 one
2 two
3 three
>>> k
'3'
>>> v
'three'
>>> print(k)
3
>>> print(v)
three
我就是想證明:for 變量 in 列表的這個結構,如果in後面只有一個元素,那它就不是列表了,但是也適用這個結構
>>> a=3
>>> a.append(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'append'
>>> a=[3]
>>> a.apend(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'apend'
>>> a.append(5)
>>> a
[3, 5]
爲進一步改進這個程序,可在遍歷字典的for 循環開頭添加一條if 語句,通過查看len(languages) 的值來確定當前的被調查者喜歡的語言是否有多種。如果他喜歡的語言有
多種,就像以前一樣顯示輸出;如果只有一種,就相應修改輸出的措辭,如顯示Sarah's favorite language is C 。 
注意
列表和字典的嵌套層級不應太多。如果嵌套層級比前面的示例多得多,很可能有更簡單的解決問題的方案。
6.4.3 在字典中存儲字典
可在字典中嵌套字典,但這樣做時,代碼可能很快複雜起來。例如,如果有多個網站用戶,每個都有獨特的用戶名,可在字典中將用戶名作爲鍵,然後將每位用戶的信息存儲在
一個字典中,並將該字典作爲與用戶名相關聯的值。在下面的程序中,對於每位用戶,我們都存儲了其三項信息:名、姓和居住地;爲訪問這些信息,我們遍歷所有的用戶名,
並訪問與每個用戶名相關聯的信息字典:
many_users.py
users = {
'aeinstein': {
'first': 'albert',
'last': 'einstein',
'location': 'princeton',
},
'mcurie': {
'first': 'marie',
'last': 'curie',
'location': 'paris',
},
}
for username, user_info in users.items():
print("\nUsername: " + username)
full_name = user_info['first'] + " " + user_info['last']
location = user_info['location']
print("\tFull name: " + full_name.title())
print("\tLocation: " + location.title())
注意此處的for k,v in u.items()  中 如果值對應的是字典或者列表,那麼v會變成字典或者列表,這個算是上面for 變量 in 列表的補充
我們首先定義了一個名爲users 的字典,其中包含兩個鍵:用戶名'aeinstein' 'mcurie' ;與每個鍵相關聯的值都是一個字典,其中包含用戶的名、姓和居住地。在
處,我們遍歷字典users ,讓Python依次將每個鍵存儲在變量username 中,並依次將與當前鍵相關聯的字典存儲在變量user_info 中。在主循環內部的處,我們將用戶名
打印出來。
處,我們開始訪問內部的字典。變量user_info 包含用戶信息字典,而該字典包含三個鍵:'first' 'last' 'location' ;對於每位用戶,我們都使用這些鍵來
生成整潔的姓名和居住地,然後打印有關用戶的簡要信息(見):
Username: aeinstein
Full name: Albert Einstein
Location: PrincetonUsername: mcurie
Full name: Marie Curie
Location: Paris
請注意,表示每位用戶的字典的結構都相同,雖然Python並沒有這樣的要求,但這使得嵌套的字典處理起來更容易。倘若表示每位用戶的字典都包含不同的鍵,for 循環內部的
代碼將更復雜。
動手試一試
6-7
:在爲完成練習6-1而編寫的程序中,再創建兩個表示人的字典,然後將這三個字典都存儲在一個名爲people 的列表中。遍歷這個列表,將其中每個人的所有
信息都打印出來。
6-8 
寵物
:創建多個字典,對於每個字典,都使用一個寵物的名稱來給它命名;在每個字典中,包含寵物的類型及其主人的名字。將這些字典存儲在一個名爲pets
的列表中,再遍歷該列表,並將寵物的所有信息都打印出來。
6-9
歡的
地方
:創建一個名爲favorite_places 的字典。在這個字典中,將三個人的名字用作鍵;對於其中的每個人,都存儲他喜歡的1~3個地方。爲讓這個練
習更有趣些,可讓一些朋友指出他們喜歡的幾個地方。遍歷這個字典,並將其中每個人的名字及其喜歡的地方打印出來。
6-10
歡的
字 :修改爲完成練習6-2而編寫的程序,讓每個人都可以有多個喜歡的數字,然後將每個人的名字及其喜歡的數字打印出來。
6-11
市 :創建一個名爲cities 的字典,其中將三個城市名用作鍵;對於每座城市,都創建一個字典,並在其中包含該城市所屬的國家、人口約數以及一個有關該
城市的事實。在表示每座城市的字典中,應包含country population fact 等鍵。將每座城市的名字以及有關它們的信息都打印出來。
6-12
展 :本章的示例足夠複雜,可以以很多方式進行擴展了。請對本章的一個示例進行擴展:添加鍵和值、調整程序要解決的問題或改進輸出的格式。
6.5 小結
在本章中,你學習了:如何定義字典,以及如何使用存儲在字典中的信息;如何訪問和修改字典中的元素,以及如何遍歷字典中的所有信息;如何遍歷字典中所有的鍵-值對、所
有的鍵和所有的值;如何在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。
在下一章中,你將學習while 循環以及如何從用戶那裏獲取輸入。這是激動人心的一章,讓你知道如何將程序變成交互性的——能夠對用戶輸入作出響應。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章