做者|Ankit Gupta
編譯|VK
來源|Towards Datas Sciencepython
在這篇文章中,我將討論字典。這是「Python中的數據結構」系列的第二篇文章。本系列的第一部分是關於列表的。數組
字典是Python中使用鍵進行索引的重要數據結構。它們是無序的項序列(鍵值對),這意味着順序不被保留。鍵是不可變的。數據結構
與列表同樣,字典的值能夠保存異構數據,即整數、浮點、字符串、NaN、布爾值、列表、數組,甚至嵌套字典。app
本文將爲你提供一個清晰的理解,並使你可以熟練地使用Python字典。機器學習
本文包括如下主題:函數
像列表是用方括號([])初始化的,字典是用花括號({})初始化的。固然,空字典的長度是零。學習
dic_a = {} # 空字典 type(dic_a) >>> dict len(dic_a) >>> 0
字典有兩個特徵:鍵和值。每一個鍵都有相應的值。鍵和值均可以是string、float、integer、NaN等類型。向字典中添加元素意味着添加鍵值對。字典由一個或多個鍵值對組成。.net
讓咱們在空字典裏增長一些元素。下面是一種方法。這裏,「A」是鍵,「Apple」是它的值。你能夠添加任意多個元素。code
# 添加第一個元素 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做爲鍵。
建立了字典以後,讓咱們看看如何訪問它們的元素。
你可使用函數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'
從字典中刪除元素意味着一塊兒刪除一個鍵值對。
可使用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()」函數刪除元素。它返回彈出(刪除)的值,並修改字典。
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'}
你能夠向字典中添加一個元素,以下所示。
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()函數經過將該對做爲參數傳遞來添加新的鍵值對。
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'}
可使用從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開始,你可使用|操做符鏈接兩個或多個字典。
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
若是要將「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'}
字典中不維護順序。字典中不維護順序。你可使用鍵或使用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)]
它是動態建立字典的一種很是有用的方法,也是動態建立字典的一種很是有用的方法。假設你要建立一個字典,其中鍵是一個整數,值是它的平方。字典生成式以下所示。
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}
假設你有兩個列表,你想用它們建立一個字典。最簡單的方法是使用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'}
我將用一個簡單的例子來解釋這一點。字典的複製機制涉及到更多的微妙之處,我建議讀者參考這篇Stack Overflow的問題以得到詳細的解釋:https://stackoverflow.com/q/3...
當你只需將現有字典(父字典)從新指派給新字典時,二者都指向同一個對象(「引用賦值」)。
考慮下面的例子,你將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'}
假設你想將鍵「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}
嵌套字典在一個字典中有一個或多個字典。下面是具備兩層嵌套的嵌套字典的最簡單示例。這裏,外部字典(第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'
你可使用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.co...
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方文檔:
http://sklearn123.com/
歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/