Python中的字典

做者|Ankit Gupta
編譯|VK
來源|Towards Datas Sciencepython

在這篇文章中,我將討論字典。這是「Python中的數據結構」系列的第二篇文章。本系列的第一部分是關於列表的。數組

字典是Python中使用鍵進行索引的重要數據結構。它們是無序的項序列(鍵值對),這意味着順序不被保留。鍵是不可變的。數據結構

與列表同樣,字典的值能夠保存異構數據,即整數、浮點、字符串、NaN、布爾值、列表、數組,甚至嵌套字典。app

本文將爲你提供一個清晰的理解,並使你可以熟練地使用Python字典。機器學習

本文包括如下主題:函數

  • 建立字典並添加元素
  • 訪問字典元素
  • 刪除字典元素
  • 添加/插入新元素
  • 合併/鏈接字典
  • 修改字典
  • 字典排序
  • 字典生成式
  • 建立字典的其餘方法
  • 複製字典
  • 重命名現有鍵
  • 嵌套字典
  • 檢查字典中是否存在鍵

1 建立字典並添加元素

像列表是用方括號([])初始化的,字典是用花括號({})初始化的。固然,空字典的長度是零。學習

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做爲鍵。

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/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'}

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.co...

歡迎關注磐創AI博客站:
http://panchuang.net/

sklearn機器學習中文官方文檔:
http://sklearn123.com/

歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/

相關文章
相關標籤/搜索