字典是Python中使用鍵進(jìn)行索引的重要數(shù)據(jù)結(jié)構(gòu),。它們是無(wú)序的項(xiàng)序列(鍵值對(duì)),,這意味著順序不被保留。鍵是不可變的,。
與列表一樣,,字典的值可以保存異構(gòu)數(shù)據(jù),即整數(shù),、浮點(diǎn),、字符串、NaN,、布爾值,、列表、數(shù)組,,甚至嵌套字典,。
本文將為你提供一個(gè)清晰的理解,并使你能夠熟練地使用Python字典。
本文包括以下主題:
- 創(chuàng)建字典并添加元素
- 訪問(wèn)字典元素
- 刪除字典元素
- 添加/插入新元素
- 合并/連接字典
- 修改字典
- 字典排序
- 字典生成式
- 創(chuàng)建字典的其他方法
- 復(fù)制字典
- 重命名現(xiàn)有鍵
- 嵌套字典
- 檢查字典中是否存在鍵
1 創(chuàng)建字典并添加元素
像列表是用方括號(hào)([])初始化的,,字典是用花括號(hào)({})初始化的,。當(dāng)然,空字典的長(zhǎng)度是零,。
dic_a = {} # 空字典
type(dic_a)
>>> dict
len(dic_a)
>>> 0
字典有兩個(gè)特征:鍵和值,。每個(gè)鍵都有相應(yīng)的值。鍵和值都可以是string,、float,、integer、NaN等類型,。向字典中添加元素意味著添加鍵值對(duì),。字典由一個(gè)或多個(gè)鍵值對(duì)組成。
讓我們?cè)诳兆值淅镌黾右恍┰?。下面是一種方法,。這里,“A”是鍵,,“Apple”是它的值,。你可以添加任意多個(gè)元素。
# 添加第一個(gè)元素
dic_a['A'] = 'Apple'
print (dic_a)
>>> {'A': 'Apple'}
# 添加第二個(gè)元素
dic_a['B'] = 'Ball'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball'}
注意:Python區(qū)分大小寫,,“A”和“a”充當(dāng)兩個(gè)不同的鍵,。
dic_a['a'] = 'apple'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'a': 'apple'}
一次初始化字典
如果你發(fā)現(xiàn)上面一個(gè)接一個(gè)添加元素的方法很煩人,那么你也可以通過(guò)指定所有鍵值對(duì)立即初始化字典,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
異構(gòu)字典
到目前為止,你的字典中有字符串作為鍵和值,。字典也可以存儲(chǔ)混合類型的數(shù)據(jù),。下面是一個(gè)有效的Python字典。
dic_b = {1: 'Ace', 'B': 123, np.nan: 99.9, 'D': np.nan, 'E': np.inf}
但是你應(yīng)該為鍵使用有意義的名稱,,因?yàn)樗鼈儽硎咀值涞乃饕?。尤其要避免使用float和np.nan作為鍵。
2 訪問(wèn)字典元素
創(chuàng)建了字典之后,,讓我們看看如何訪問(wèn)它們的元素,。
訪問(wèn)鍵和值
你可以使用函數(shù)dict.keys()和dict.values()分別訪問(wèn)鍵和值。還可以使用items()函數(shù)訪問(wèn)元組形式的鍵和值,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.keys()
>>> dict_keys(['A', 'B', 'C'])
dic_a.values()
>>> dict_values(['Apple', 'Ball', 'Cat'])
dic_a.items()
>>> dict_items([('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')])
或者,,也可以使用“for”循環(huán)一次訪問(wèn)/打印一個(gè)。
# 打印鍵
for key in dic_a.keys():
print (key, end=' ')
>>> A B C
#############################
# 打印值
for key in dic_a.values():
print (key, end=' ')
>>> Apple Ball Cat
你可以避免兩個(gè)“for”循環(huán),,并使用items()訪問(wèn)鍵和值,。“for”循環(huán)將遍歷items()返回的鍵值對(duì)。這里,,鍵和值是任意變量名,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
for key, value in dic_a.items():
print (key, value)
>>> A Apple
B Ball
C Cat
訪問(wèn)單個(gè)元素
無(wú)法使用數(shù)字索引訪問(wèn)字典項(xiàng)。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a[0]
>>> ----> 1 dic_a[0]
KeyError: 0
你需要使用鍵從字典中訪問(wèn)相應(yīng)的值,。
# 獲取'Apple'的值
dic_a['A']
>>> 'Apple'
# 獲取'Cat'的值
dic_a['C']
>>> 'Cat'
如果字典中不存在鍵,,則會(huì)出現(xiàn)錯(cuò)誤。
dic_a['Z']
>>> KeyError Traceback (most recent call last)
----> 1 dic_a['Z']
KeyError: 'Z'
如果希望在不存在鍵的情況下避免此類鍵錯(cuò)誤,,可以使用get()函數(shù),。如果鍵不存在,則返回None,。也可以使用自定義消息返回,。
print (dic_a.get('Z'))
>>> None
# 自定義返回消息
print (dic_a.get('Z', 'Key does not exist'))
>>> Key does not exist
訪問(wèn)列表中的字典元素
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
list(dic_a.keys())[0]
>>> 'A'
list(dic_a.keys())[-1]
>>> 'C'
list(dic_a.values())[0]
>>> 'Apple'
list(dic_a.values())[-1]
>>> 'Cat'
3 刪除字典元素
從字典中刪除元素意味著一起刪除一個(gè)鍵值對(duì)。
使用del
可以使用del關(guān)鍵字和要?jiǎng)h除其值的鍵刪除字典元素,。刪除是in-place,,這意味著刪除后不需要重新分配字典的值。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
# 刪除“A”:“Apple”的鍵值對(duì)
del dic_a['A']
print (dic_a)
>>> {'B': 'Ball', 'C': 'Cat'}
# 刪除“C”:“Cat”的鍵值對(duì)
del dic_a['C']
print (dic_a)
>>> {'B': 'Ball'}
使用pop()
你還可以使用“pop()”函數(shù)刪除元素,。它返回彈出(刪除)的值,,并修改字典。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.pop('A')
>>> 'Apple'
print (dic_a)
# {'B': 'Ball', 'C': 'Cat'}
在上述兩種方法中,,如果要?jiǎng)h除的鍵不存在于字典中,,則會(huì)出現(xiàn)KeyError。在“pop()”的情況下,,如果鍵不存在,,可以指定要顯示的錯(cuò)誤消息。
key_to_delete = 'E'
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.pop(key_to_delete, f'Key {key_to_delete} does not exist.')
>>> 'Key E does not exist.'
刪除多個(gè)元素
沒(méi)有直接的方法,,但是你可以使用一個(gè)“for”循環(huán),,如下所示。
to_delete = ['A', 'C']
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
for key in to_delete:
del dic_a[key]
print (dic_a)
>>> {'B': 'Ball'}
4 添加/插入新元素
你可以向字典中添加一個(gè)元素,,如下所示,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a['D'] = 'Dog'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
dic_a['E'] = 'Egg'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Egg'}
如果你正在添加的鍵已經(jīng)存在,則將覆蓋現(xiàn)有值,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a['A'] = 'Adam' # 鍵“A”已經(jīng)存在,,值為“Apple”
print (dic_a)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}
使用update()
還可以使用update()函數(shù)通過(guò)將該對(duì)作為參數(shù)傳遞來(lái)添加新的鍵值對(duì)。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.update({'D': 'Dog'})
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
函數(shù)還允許你同時(shí)向現(xiàn)有字典添加多個(gè)鍵值對(duì),。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = {'D':'Dog', 'E':'Egg'}
dic_a.update(dic_b)
print(dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Egg'}
5 合并/連接字典
可以使用從Python 3.5開始的解包操作符(**)合并兩個(gè)或多個(gè)字典,。
dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}
dic_merged = {**dic_a, **dic_b}
print (dic_merged)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
如果不想創(chuàng)建新字典,但只想將dic_b添加到現(xiàn)有dic_a中,,你可以簡(jiǎn)單地更新前面所示的第一個(gè)字典,。
dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}
dic_a.update(dic_b)
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
在連接時(shí)如何處理重復(fù)鍵,?
Python字典的一個(gè)特點(diǎn)是它們不能有重復(fù)的鍵,即鍵不能出現(xiàn)兩次,。那么,,如果連接兩個(gè)或多個(gè)字典,其中包含一個(gè)或多個(gè)公共鍵,,會(huì)發(fā)生什么情況,。
答案是,最后一個(gè)合并字典中的鍵值對(duì)(按合并順序)將繼續(xù)存在,。在下面的示例中,,所有三個(gè)字典中都存在鍵“A”,因此,,最終字典從最后一個(gè)合并字典(dic_c)中獲取值,。
dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'A': 'Apricot'}
dic_c = {'A': 'Adam', 'E': 'Egg'}
dic_merged = {**dic_a, **dic_b, **dic_c}
print (dic_merged)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat', 'E': 'Egg'}
謹(jǐn)慎的話
我剛說(shuō)字典不能有重復(fù)的鍵。嚴(yán)格地說(shuō),,你可以定義一個(gè)具有重復(fù)鍵的字典,,但是,打印時(shí),,只能打印最后一個(gè),。如下所示的dic_a,只返回唯一的鍵,,對(duì)于重復(fù)的鍵('A),,只返回最后一個(gè)值。
dic_a = {'A': 'Apple', 'B': 'Ball', 'A': 'Apricot', 'A': 'Assault'}
print (dic_a)
>>> {'A': 'Assault', 'B': 'Ball'}
Python 3.9中的更簡(jiǎn)單方法+
從Python 3.9開始,,你可以使用|操作符連接兩個(gè)或多個(gè)字典,。
dic_a = {'A': 'Apple', 'B': 'Ball'}
dic_b = {'C': 'Cat', 'D': 'Dog'}
dic_c = dic_a | dic_b
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
# 連接兩個(gè)以上的字典
dic_d = dic_a | dic_b | dic_c
6 修改字典
如果要將“A”的值從“Apple”更改為“Apricot”,可以使用一個(gè)簡(jiǎn)單的賦值,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a['A'] = 'Apricot'
print (dic_a)
>>> {'A': 'Apricot', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
7 字典排序
字典中不維護(hù)順序,。字典中不維護(hù)順序。你可以使用鍵或使用sorted()函數(shù)的值對(duì)字典進(jìn)行排序,。
按鍵排序
如果鍵是字符串,它們將按字母順序排序,。在字典中,,我們有兩個(gè)主要元素:鍵和值。因此,,在對(duì)鍵進(jìn)行排序時(shí),,我們使用第一個(gè)元素,即鍵,,因此,,lambda函數(shù)中使用的索引是“[0]”,。關(guān)于lambda函數(shù)的更多信息,可以閱讀這篇文章,。
dic_a = {'B': 100, 'C': 10, 'D': 90, 'A': 40}
sorted(dic_a.items(), key=lambda x: x[0])
>>> [('A', 40), ('B', 100), ('C', 10), ('D', 90)]
排序不是in-place,。如下所示,如果現(xiàn)在打印字典,,它將保持無(wú)序,,與最初初始化時(shí)一樣。你必須在分類后重新賦值,。
# 如果你把這個(gè)字典打印出來(lái),,它還是沒(méi)有順序
print (dic_a)
>>> {'B': 100, 'C': 10, 'D': 90, 'A': 40}
如果要按逆序排序,請(qǐng)指定關(guān)鍵字reverse=True,。
sorted(dic_a.items(), key=lambda x: x[0], reverse=True)
>>> [('D', 90), ('C', 10), ('B', 100), ('A', 40)]
按值排序
要根據(jù)字典的值對(duì)字典進(jìn)行排序,,需要在lambda函數(shù)中使用索引“[1]”。
dic_a = {'B': 100, 'C': 10, 'D': 90, 'A': 40}
sorted(dic_a.items(), key=lambda x: x[1])
>>> [('C', 10), ('A', 40), ('D', 90), ('B', 100)]
8 字典生成式
它是動(dòng)態(tài)創(chuàng)建字典的一種非常有用的方法,,也是動(dòng)態(tài)創(chuàng)建字典的一種非常有用的方法,。假設(shè)你要?jiǎng)?chuàng)建一個(gè)字典,其中鍵是一個(gè)整數(shù),,值是它的平方,。字典生成式如下所示。
dic_c = {i: i**2 for i in range(5)}
print (dic_c)
>>> {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
如果你希望你的鍵是字符串,,可以使用'f-strings',。
dic_c = {f'{i}': i**2 for i in range(5)}
print (dic_c)
>>> {'0': 0, '1': 1, '2': 4, '3': 9, '4': 16}
9 創(chuàng)建字典的其他方法
從列表創(chuàng)建字典
假設(shè)你有兩個(gè)列表,你想用它們創(chuàng)建一個(gè)字典,。最簡(jiǎn)單的方法是使用dict()構(gòu)造函數(shù),。
names = ['Sam', 'Adam', 'Tom', 'Harry']
marks = [90, 85, 55, 70]
dic_grades = dict(zip(names, marks))
print (dic_grades)
>>> {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}
你還可以將這兩個(gè)列表壓縮在一起,并使用前面所示的字典生成式創(chuàng)建字典,。
dic_grades = {k:v for k, v in zip(names, marks)}
print (dic_grades)
>>> {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}
傳遞鍵值對(duì)
你還可以將用逗號(hào)分隔的鍵值對(duì)列表傳遞給dict()構(gòu)造,,它將返回一個(gè)字典。
dic_a = dict([('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')])
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
如果你的鍵是字符串,,你甚至可以使用更簡(jiǎn)單的初始化,,只使用變量作為鍵。
dic_a = dict(A='Apple', B='Ball', C='Cat')
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
10 復(fù)制字典
我將用一個(gè)簡(jiǎn)單的例子來(lái)解釋這一點(diǎn),。字典的復(fù)制機(jī)制涉及到更多的微妙之處,,我建議讀者參考這篇Stack Overflow的問(wèn)題以獲得詳細(xì)的解釋:
https:///q/3975376/4932316
參考賦值
當(dāng)你只需將現(xiàn)有字典(父字典)重新指派給新字典時(shí),兩者都指向同一個(gè)對(duì)象(“引用賦值”),。
考慮下面的例子,,你將dic_a重新分配給dic_b。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a # 簡(jiǎn)單重新分配
現(xiàn)在,,如果你修改dic_b(例如添加一個(gè)新元素),,你會(huì)注意到該更改也會(huì)反映在dic_a中,。
dic_b['D'] = 'Dog'
print (dic_b)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
淺拷貝
使用copy()函數(shù)創(chuàng)建一個(gè)淺拷貝。在淺拷貝中,,這兩個(gè)字典充當(dāng)兩個(gè)獨(dú)立的對(duì)象,,它們的內(nèi)容仍然共享相同的引用。如果在新字典(淺表副本)中添加新的鍵值對(duì),,它將不會(huì)顯示在父字典中,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()
dic_b['D'] = 'Dog'
# New,淺拷貝,,有新的鍵值對(duì)
print (dic_b)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
# 父字典沒(méi)有新的鍵值對(duì)
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
現(xiàn)在,,父字典(“dic_a”)中的內(nèi)容是否會(huì)更改取決于值的類型。例如,,在下面,,內(nèi)容是不可變的簡(jiǎn)單字符串。因此,,更改給定鍵(在本例中為a)的“dic_b”中的值不會(huì)更改“dic_a”中鍵“a”的值,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()
# 在淺拷貝中將現(xiàn)有鍵替換為新值
dic_b['A'] = 'Adam'
print (dic_b)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}
# 字符串是不可變的,所以'Apple'在dic_a中不會(huì)變成'Adam'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
但是,,如果“dic_A”中鍵“A”的值是一個(gè)列表,,那么在“dic_b”中更改其值將反映“dic_A”(父字典)中的更改,因?yàn)榱斜硎强勺兊摹?/p>
dic_a = {'A': ['Apple'], 'B': 'Ball', 'C': 'Cat'}
# 淺拷貝
dic_b = dic_a.copy()
dic_b['A'][0] = 'Adam'
print (dic_b)
>>> {'A': ['Adam'], 'B': 'Ball', 'C': 'Coal'}
# 列表是可變的,,因此更改也會(huì)反映在dic_a中
print (dic_a)
>>> {'A': ['Adam'], 'B': 'Ball', 'C': 'Cat'}
11 重命名現(xiàn)有鍵
假設(shè)你想將鍵“Adam”替換為“Alex”,。你可以使用pop函數(shù),因?yàn)樗鼊h除傳遞的鍵(這里是Adam)并返回刪除的值(這里是85),。所以你一槍打死兩只鳥,。
使用返回的(已刪除)值將該值分配給新鍵(這里是Alex)??赡苓€有更復(fù)雜的情況,,其中的鍵是元組。這種情況不在本文的討論范圍之內(nèi),。
dic_a = {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}
dic_a['Alex'] = dic_a.pop('Adam')
print (dic_a)
>>> {'Sam': 90, 'Tom': 55, 'Harry': 70, 'Alex': 85}
12 嵌套字典
嵌套字典在一個(gè)字典中有一個(gè)或多個(gè)字典,。下面是具有兩層嵌套的嵌套字典的最簡(jiǎn)單示例。這里,,外部字典(第1層)只有一個(gè)鍵值對(duì),。但是,現(xiàn)在值本身就是一個(gè)字典,。
dic_a = {'A': {'B': 'Ball'}}
dic_a['A']
>>> {'B': 'Ball'}
type(dic_a['A'])
>>> dict
如果你想進(jìn)一步訪問(wèn)內(nèi)部字典(第2層)的鍵值對(duì),現(xiàn)在需要使用dic_a['a']作為字典,。
dic_a['A']['B']
>>> 'Ball'
三層字典
讓我們添加一個(gè)嵌套字典的附加層?,F(xiàn)在,,dic_a['a']本身是一個(gè)嵌套字典,與上面最簡(jiǎn)單的嵌套字典不同,。
dic_a = {'A': {'B': {'C': 'Cat'}}}
# 第1層
dic_a['A']
>>> {'B': {'C': 'Cat'}}
# 第2層
dic_a['A']['B']
>>> {'C': 'Cat'}
# 第3層
dic_a['A']['B']['C']
>>> 'Cat'
13 檢查字典中是否存在鍵
你可以使用in運(yùn)算符查找字典中是否存在特定鍵,。
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
'A' in dic_a
# True
'E' in dic_a
# False
在上面的代碼中,你不需要使用“in dic_a.keys( )”,,因?yàn)椤癷n dic_a”已經(jīng)在鍵中查找了,。