作者|Ankit Gupta
編譯|VK
來源|Towards Datas Science
在這篇文章中,我將討論字典,這是“Python中的資料結構”系列的第二篇文章,本系列的第一部分是關于串列的,
字典是Python中使用鍵進行索引的重要資料結構,它們是無序的項序列(鍵值對),這意味著順序不被保留,鍵是不可變的,
與串列一樣,字典的值可以保存異構資料,即整數、浮點、字串、NaN、布林值、串列、陣列,甚至嵌套字典,
本文將為你提供一個清晰的理解,并使你能夠熟練地使用Python字典,
本文包括以下主題:
-
創建字典并添加元素
-
訪問字典元素
-
洗掉字典元素
-
添加/插入新元素
-
合并/連接字典
-
修改字典
-
字典排序
-
字典生成式
-
創建字典的其他方法
-
復制字典
-
重命名現有鍵
-
嵌套字典
-
檢查字典中是否存在鍵
1 創建字典并添加元素
像串列是用方括號([])初始化的,字典是用花括號({})初始化的,當然,空字典的長度是零,
dic_a = {} # 空字典
type(dic_a)
>>> dict
len(dic_a)
>>> 0
字典有兩個特征:鍵和值,每個鍵都有相應的值,鍵和值都可以是string、float、integer、NaN等型別,向字典中添加元素意味著添加鍵值對,字典由一個或多個鍵值對組成,
讓我們在空字典里增加一些元素,下面是一種方法,這里,“A”是鍵,“Apple”是它的值,你可以添加任意多個元素,
# 添加第一個元素
dic_a['A'] = 'Apple'
print (dic_a)
>>> {'A': 'Apple'}
# 添加第二個元素
dic_a['B'] = 'Ball'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball'}
注意:Python區分大小寫,“A”和“a”充當兩個不同的鍵,
dic_a['a'] = 'apple'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'a': 'apple'}
一次初始化字典
如果你發現上面一個接一個添加元素的方法很煩人,那么你也可以通過指定所有鍵值對立即初始化字典,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
異構字典
到目前為止,你的字典中有字串作為鍵和值,字典也可以存盤混合型別的資料,下面是一個有效的Python字典,
dic_b = {1: 'Ace', 'B': 123, np.nan: 99.9, 'D': np.nan, 'E': np.inf}
但是你應該為鍵使用有意義的名稱,因為它們表示字典的索引,尤其要避免使用float和np.nan作為鍵,
2 訪問字典元素
創建了字典之后,讓我們看看如何訪問它們的元素,
訪問鍵和值
你可以使用函式dict.keys()和dict.values()分別訪問鍵和值,還可以使用items()函式訪問元組形式的鍵和值,
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”回圈一次訪問/列印一個,
# 列印鍵
for key in dic_a.keys():
print (key, end=' ')
>>> A B C
#############################
# 列印值
for key in dic_a.values():
print (key, end=' ')
>>> Apple Ball Cat
你可以避免兩個“for”回圈,并使用items()訪問鍵和值,“for”回圈將遍歷items()回傳的鍵值對,這里,鍵和值是任意變數名,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
for key, value in dic_a.items():
print (key, value)
>>> A Apple
B Ball
C Cat
訪問單個元素
無法使用數字索引訪問字典項,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a[0]
>>> ----> 1 dic_a[0]
KeyError: 0
你需要使用鍵從字典中訪問相應的值,
# 獲取"Apple"的值
dic_a['A']
>>> 'Apple'
# 獲取"Cat"的值
dic_a['C']
>>> 'Cat'
如果字典中不存在鍵,則會出現錯誤,
dic_a['Z']
>>> KeyError Traceback (most recent call last)
----> 1 dic_a['Z']
KeyError: 'Z'
如果希望在不存在鍵的情況下避免此類鍵錯誤,可以使用get()函式,如果鍵不存在,則回傳None,也可以使用自定義訊息回傳,
print (dic_a.get('Z'))
>>> None
# 自定義回傳訊息
print (dic_a.get('Z', 'Key does not exist'))
>>> Key does not exist
訪問串列中的字典元素
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 洗掉字典元素
從字典中洗掉元素意味著一起洗掉一個鍵值對,
使用del
可以使用del關鍵字和要洗掉其值的鍵洗掉字典元素,洗掉是in-place,這意味著洗掉后不需要重新分配字典的值,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
# 洗掉“A”:“Apple”的鍵值對
del dic_a['A']
print (dic_a)
>>> {'B': 'Ball', 'C': 'Cat'}
# 洗掉“C”:“Cat”的鍵值對
del dic_a['C']
print (dic_a)
>>> {'B': 'Ball'}
使用pop()
你還可以使用“pop()”函式洗掉元素,它回傳彈出(洗掉)的值,并修改字典,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.pop('A')
>>> 'Apple'
print (dic_a)
# {'B': 'Ball', 'C': 'Cat'}
在上述兩種方法中,如果要洗掉的鍵不存在于字典中,則會出現KeyError,在“pop()”的情況下,如果鍵不存在,可以指定要顯示的錯誤訊息,
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.'
洗掉多個元素
沒有直接的方法,但是你可以使用一個“for”回圈,如下所示,
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 添加/插入新元素
你可以向字典中添加一個元素,如下所示,
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'}
如果你正在添加的鍵已經存在,則將覆寫現有值,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a['A'] = 'Adam' # 鍵“A”已經存在,值為“Apple”
print (dic_a)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}
使用update()
還可以使用update()函式通過將該對作為引數傳遞來添加新的鍵值對,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a.update({'D': 'Dog'})
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
函式還允許你同時向現有字典添加多個鍵值對,
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開始的解包運算子(**)合并兩個或多個字典,
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'}
如果不想創建新字典,但只想將dic_b添加到現有dic_a中,你可以簡單地更新前面所示的第一個字典,
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'}
在連接時如何處理重復鍵?
Python字典的一個特點是它們不能有重復的鍵,即鍵不能出現兩次,那么,如果連接兩個或多個字典,其中包含一個或多個公共鍵,會發生什么情況,
答案是,最后一個合并字典中的鍵值對(按合并順序)將繼續存在,在下面的示例中,所有三個字典中都存在鍵“A”,因此,最終字典從最后一個合并字典(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'}
謹慎的話
我剛說字典不能有重復的鍵,嚴格地說,你可以定義一個具有重復鍵的字典,但是,列印時,只能列印最后一個,如下所示的dic_a,只回傳唯一的鍵,對于重復的鍵('A),只回傳最后一個值,
dic_a = {'A': 'Apple', 'B': 'Ball', 'A': 'Apricot', 'A': 'Assault'}
print (dic_a)
>>> {'A': 'Assault', 'B': 'Ball'}
Python 3.9中的更簡單方法+
從Python 3.9開始,你可以使用|運算子連接兩個或多個字典,
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'}
# 連接兩個以上的字典
dic_d = dic_a | dic_b | dic_c
6 修改字典
如果要將“A”的值從“Apple”更改為“Apricot”,可以使用一個簡單的賦值,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_a['A'] = 'Apricot'
print (dic_a)
>>> {'A': 'Apricot', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
7 字典排序
字典中不維護順序,字典中不維護順序,你可以使用鍵或使用sorted()函式的值對字典進行排序,
按鍵排序
如果鍵是字串,它們將按字母順序排序,在字典中,我們有兩個主要元素:鍵和值,因此,在對鍵進行排序時,我們使用第一個元素,即鍵,因此,lambda函式中使用的索引是“[0]”,關于lambda函式的更多資訊,可以閱讀這篇文章,
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,如下所示,如果現在列印字典,它將保持無序,與最初初始化時一樣,你必須在分類后重新賦值,
# 如果你把這個字典列印出來,它還是沒有順序
print (dic_a)
>>> {'B': 100, 'C': 10, 'D': 90, 'A': 40}
如果要按逆序排序,請指定關鍵字reverse=True,
sorted(dic_a.items(), key=lambda x: x[0], reverse=True)
>>> [('D', 90), ('C', 10), ('B', 100), ('A', 40)]
按值排序
要根據字典的值對字典進行排序,需要在lambda函式中使用索引“[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 字典生成式
它是動態創建字典的一種非常有用的方法,也是動態創建字典的一種非常有用的方法,假設你要創建一個字典,其中鍵是一個整數,值是它的平方,字典生成式如下所示,
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 創建字典的其他方法
從串列創建字典
假設你有兩個串列,你想用它們創建一個字典,最簡單的方法是使用dict()建構式,
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}
你還可以將這兩個串列壓縮在一起,并使用前面所示的字典生成式創建字典,
dic_grades = {k:v for k, v in zip(names, marks)}
print (dic_grades)
>>> {'Sam': 90, 'Adam': 85, 'Tom': 55, 'Harry': 70}
傳遞鍵值對
你還可以將用逗號分隔的鍵值對串列傳遞給dict()構造,它將回傳一個字典,
dic_a = dict([('A', 'Apple'), ('B', 'Ball'), ('C', 'Cat')])
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
如果你的鍵是字串,你甚至可以使用更簡單的初始化,只使用變數作為鍵,
dic_a = dict(A='Apple', B='Ball', C='Cat')
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
10 復制字典
我將用一個簡單的例子來解釋這一點,字典的復制機制涉及到更多的微妙之處,我建議讀者參考這篇Stack Overflow的問題以獲得詳細的解釋:https://stackoverflow.com/q/3975376/4932316
參考賦值
當你只需將現有字典(父字典)重新指派給新字典時,兩者都指向同一個物件(“參考賦值”),
考慮下面的例子,你將dic_a重新分配給dic_b,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a # 簡單重新分配
現在,如果你修改dic_b(例如添加一個新元素),你會注意到該更改也會反映在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()函式創建一個淺拷貝,在淺拷貝中,這兩個字典充當兩個獨立的物件,它們的內容仍然共享相同的參考,如果在新字典(淺表副本)中添加新的鍵值對,它將不會顯示在父字典中,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()
dic_b['D'] = 'Dog'
# New,淺拷貝,有新的鍵值對
print (dic_b)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
# 父字典沒有新的鍵值對
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
現在,父字典(“dic_a”)中的內容是否會更改取決于值的型別,例如,在下面,內容是不可變的簡單字串,因此,更改給定鍵(在本例中為a)的“dic_b”中的值不會更改“dic_a”中鍵“a”的值,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
dic_b = dic_a.copy()
# 在淺拷貝中將現有鍵替換為新值
dic_b['A'] = 'Adam'
print (dic_b)
>>> {'A': 'Adam', 'B': 'Ball', 'C': 'Cat'}
# 字串是不可變的,所以'Apple'在dic_a中不會變成'Adam'
print (dic_a)
>>> {'A': 'Apple', 'B': 'Ball', 'C': 'Cat'}
但是,如果“dic_A”中鍵“A”的值是一個串列,那么在“dic_b”中更改其值將反映“dic_A”(父字典)中的更改,因為串列是可變的,
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'}
# 串列是可變的,因此更改也會反映在dic_a中
print (dic_a)
>>> {'A': ['Adam'], 'B': 'Ball', 'C': 'Cat'}
11 重命名現有鍵
假設你想將鍵“Adam”替換為“Alex”,你可以使用pop函式,因為它洗掉傳遞的鍵(這里是Adam)并回傳洗掉的值(這里是85),所以你一槍打死兩只鳥,
使用回傳的(已洗掉)值將該值分配給新鍵(這里是Alex),可能還有更復雜的情況,其中的鍵是元組,這種情況不在本文的討論范圍之內,
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 嵌套字典
嵌套字典在一個字典中有一個或多個字典,下面是具有兩層嵌套的嵌套字典的最簡單示例,這里,外部字典(第1層)只有一個鍵值對,但是,現在值本身就是一個字典,
dic_a = {'A': {'B': 'Ball'}}
dic_a['A']
>>> {'B': 'Ball'}
type(dic_a['A'])
>>> dict
如果你想進一步訪問內部字典(第2層)的鍵值對,現在需要使用dic_a['a']作為字典,
dic_a['A']['B']
>>> 'Ball'
三層字典
讓我們添加一個嵌套字典的附加層,現在,dic_a['a']本身是一個嵌套字典,與上面最簡單的嵌套字典不同,
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運算子查找字典中是否存在特定鍵,
dic_a = {'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog'}
'A' in dic_a
# True
'E' in dic_a
# False
在上面的代碼中,你不需要使用“in dic_a.keys( )”,因為“in dic_a”已經在鍵中查找了,
原文鏈接:https://towardsdatascience.com/dictionaries-in-python-84b05bb95629
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/152086.html
標籤:其他
