軌道
/
Python
Python
/
課程大綱
/
字典方法
字典

字典方法 在 Python

2 個練習

關於 字典方法

Python 的 dict 類別提供了許多處理字典的實用方法。 其中一些已經在 dict 的概念頁中介紹過。 這裡我們會再介紹幾個,以及一些疊代與操作字典的技巧。

  • <dict>.setdefault() 會自動新增鍵,而不會引發 KeyError。
  • <dict>.fromkeys(<iterable>, <default value>) 可以從任意數量的可疊代物件建立新的 dict。
  • <dict>.keys()、<dict>.values() 與 <dict>.items() 提供方便好用的疊代器。
  • sorted(<dict>.items()) 可以輕鬆重新排序 dict 中的項目。
  • <dict_one>.update(<dict_two>) 會用另一個 dict 中重疊的值來更新某個 dict。
  • <dict> | <other_dict> 與 <dict> |= <other_dict> 會透過運算子合併或更新兩個 dict。
  • reversed(<dict>.keys())、reversed(<dict>.values()) 或 reversed(<dict>.items()) 會產生_反轉_的檢視。
  • <dict>.popitem() 會移除並回傳一組 key、value 配對。

用 setdefault() 無錯誤地插入

字典概念先前介紹過,<dict>.get(<key>, <default value>) 會回傳既有的 value,或者當字典中找不到某個 key 時回傳 default value,藉此避免 KeyError。 當你不想加入額外的錯誤處理,卻又無法確定要找的 key 是否存在時,這個方法就很好用。

若要進行同樣「安全」(不會引發 KeyError)的插入操作,可以使用 <dict>.setdefault(<key>, <default value>) 方法。 <dict>.setdefault(<key>, <default value>) 會在字典中找到 key 時回傳 value。 如果沒找到這個鍵,它會_插入_ (key, default value) 配對,並回傳 default value 供使用。

>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}

# Looking for the value associated with key "Rock Brown".The key does not exist, 
# so it is added with the default value, and the value is returned.
>>> palette.setdefault('Rock Brown', '#694605')
'#694605'

# The (key, default value) pair has now been added to the dictionary.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}

用 fromkeys() 從可疊代物件填入字典

若要快速用各種 keys 與預設值填入字典,這個_類別方法_ fromkeys(<iterable>, <default value>) 會逐一疊代由 keys 組成的可疊代物件,並建立新的 dict。 所有 values 都會被設為提供的 default value:

>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')

{'Grassy Green': 'fill in hex color here',
 'Purple Mountains Majesty': 'fill in hex color here',
 'Misty Mountain Pink': 'fill in hex color here'}

用 .popitem() 移除並回傳鍵值配對

.popitem() 會從字典移除並回傳單一組 (key, value) 配對。 配對會以後進先出(LIFO)的順序回傳。 如果字典是空的,呼叫 popitem() 會引發 KeyError:

>>> palette_I = {'Grassy Green': '#9bc400', 
                 'Purple Mountains Majesty': '#8076a3', 
                 'Misty Mountain Pink': '#f9c5bd'}
>>> palette_I.popitem()
('Misty Mountain Pink', '#f9c5bd')

>>> palette_I.popitem()
('Purple Mountains Majesty', '#8076a3')

>>> palette_I.popitem()
('Grassy Green', '#9bc400')

# All (key, value) pairs have been removed.
>>> palette_I.popitem()
Traceback (most recent call last):
  line 1, in <module>
    palette_I.popitem()
KeyError: 'popitem(): dictionary is empty'

透過檢視疊代字典中的項目

.keys()、.values() 與 .items() 方法會回傳字典的可疊代檢視。

這些檢視可以讓你輕鬆地迴圈走訪項目,而不會更動它們。 檢視也是_動態_的:當底層的字典資料改變時,相關的 view object 也會反映這個變化:

>>> palette_I = {'Grassy Green': '#9bc400', 
                 'Purple Mountains Majesty': '#8076a3', 
                 'Misty Mountain Pink': '#f9c5bd'}

# Using .keys() returns a list of keys.
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])

# Using .values() returns a list of values.
>>> palette_I.values()
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])

# Using .items() returns a list of (key, value) tuples.
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])

# Views are dynamic.  Changing values in the dict 
# changes all of the associated views.
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
>>> palette_I['Deep Red'] = '#932432'

>>> palette_I.values()
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])

>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])

>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])

.keys()、.values() 與 .items() 的更多說明

在 Python 3.7+ 中,dicts 會保留項目插入的順序,因此使用 .keys()、.values() 或 .items() 時,可以採用先進先出(FIFO)的疊代順序。

在 Python 3.8+ 中,檢視也是_可反轉_的。 只要使用 reversed(<dict>.keys())、reversed(<dict>.values()) 或 reversed(<dict>.items()),就能以後進先出(LIFO)的順序疊代鍵、值或 (key, value) 配對:

>>> palette_II = {'Factory Stone Purple': '#7c677f', 
                  'Green Treeline': '#478559', 
                  'Purple baseline': '#161748'}
>>> for item in palette_II.items():
...     print(item)
...
('Factory Stone Purple', '#7c677f')
('Green Treeline', '#478559')
('Purple baseline', '#161748')

>>> for item in reversed(palette_II.items()):
...     print(item)
...
('Purple baseline', '#161748')
('Green Treeline', '#478559')
('Factory Stone Purple', '#7c677f')

用 .update() 合併字典

<dict_one>.update(<dict_two>) 可以用來_合併_兩個字典。 這個方法會取出 <dict_two> 的 (key,value) 配對,並將它們寫入 <dict_one>:

>>> palette_I = {'Grassy Green': '#9bc400',
                 'Purple Mountains Majesty': '#8076a3',
                  'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
                  'Green Treeline': '#478559',
                  'Purple Baseline': '#161748'}

>>> palette_I.update(palette_II)

# Note that new items from palette_II are added.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}

當兩個字典的鍵_重疊_時,dict_one 中的 value 會被 dict_two 中對應的 value 覆寫:

>>> palette_I = {'Grassy Green': '#9bc400', 
                 'Purple Mountains Majesty': '#8076a3', 
                 'Misty Mountain Pink': '#f9c5bd', 
                 'Factory Stone Purple': '#7c677f', 
                 'Green Treeline': '#478559', 
                 'Purple baseline': '#161748'}
                   
>>> palette_III = {'Grassy Green': (155, 196, 0), 
                   'Purple Mountains Majesty': (128, 118, 163),
                   'Misty Mountain Pink': (249, 197, 189)}
>>> palette_I.update(palette_III)

# Overlapping values in palette_I are replaced with 
# values from palette_III
>>> palette_I
{'Grassy Green': (155, 196, 0),
  'Purple Mountains Majesty': (128, 118, 163), 
  'Misty Mountain Pink': (249, 197, 189), 
  'Factory Stone Purple': '#7c677f', 
  'Green Treeline': '#478559', 'Purple baseline': '#161748'}

使用聯集(| 與 |=)運算子合併或更新字典

Python 3.9 導入了另一種合併 dicts 的方式:union 運算子。 dict_one | dict_two 會建立一個新字典,內容由 dict_one 與 dict_two 的 (key, value) 配對組成。 當兩個字典共用鍵時,以 dict_two 的值為優先。

>>> palette_I = {'Grassy Green': '#9bc400', 
                 'Purple Mountains Majesty': '#8076a3', 
                 'Misty Mountain Pink': '#f9c5bd'}

>>> palette_II = {'Factory Stone Purple': '#7c677f', 
                  'Green Treeline': '#478559', 
                  'Purple baseline': '#161748'}

>>> new_dict = palette_I | palette_II
>>> new_dict
...
{'Grassy Green': '#9bc400',
 'Purple Mountains Majesty': '#8076a3',
 'Misty Mountain Pink': '#f9c5bd',
 'Factory Stone Purple': '#7c677f',
 'Green Treeline': '#478559',
 'Purple baseline': '#161748'}

dict_one |= other 的行為類似 <dict_one>.update(<other>),但這裡的 other 可以是 dict,也可以是 (key, value) 配對的可疊代物件:

>>> palette_III = {'Grassy Green': (155, 196, 0),
                   'Purple Mountains Majesty': (128, 118, 163),
                   'Misty Mountain Pink': (249, 197, 189)}
>>> new_dict |= palette_III
>>> new_dict
...
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}

排序字典

字典沒有內建的排序方法。 不過,可以搭配 .items() 使用內建函式 sorted() 來排序 dict 的_檢視_。 排序後的檢視接著可以用來建立新的字典。 除非指定_排序鍵_,否則預設會依字典的 keys 排序。

# Default ordering for a dictionary is last in, first out (LIFO).
>>> color_palette = {'Grassy Green': '#9bc400', 
                    'Purple Mountains Majesty': '#8076a3', 
                    'Misty Mountain Pink': '#f9c5bd', 
                    'Factory Stone Purple': '#7c677f', 
                    'Green Treeline': '#478559', 
                    'Purple baseline': '#161748'}
 
 
# The default sort order for a dictionary uses the keys.
>>> sorted_palette = dict(sorted(color_palette.items()))
>>> sorted_palette
{'Factory Stone Purple': '#7c677f',
 'Grassy Green': '#9bc400',
 'Green Treeline': '#478559',
 'Misty Mountain Pink': '#f9c5bd',
 'Purple Mountains Majesty': '#8076a3',
 'Purple baseline': '#161748'}


# A sort key can be provided in the form
# of an anonymous function (lambda). 
>>> value_sorted_palette = dict(sorted(color_palette.items(), key=lambda color: color[1]))
>>> value_sorted_palette
{'Purple baseline': '#161748',
 'Green Treeline': '#478559',
 'Factory Stone Purple': '#7c677f',
 'Purple Mountains Majesty': '#8076a3',
 'Grassy Green': '#9bc400',
 'Misty Mountain Pink': '#f9c5bd'} 

轉置字典的鍵與值

要在字典中可靠地交換鍵與值需要費點工夫,但可以透過使用 dict.items() 的 loop,或是在字典推導式中完成。 安全地交換前提是 dict 的鍵與值都是_可雜湊_的。

color_reference = {'Purple Mountains Majesty': '#8076a3',
                   'Misty Mountain Pink': '#f9c5bd',
                   'Factory Stone Purple': '#7c677f',
                   'Green Treeline': '#478559',
                   'Purple baseline': '#161748'}

# Creating a new dictionary to hold the swapped entries.
>>> swapped_color_reference = {}

# Iterating through the dictionary, using values as keys.
>>> for key, value in color_reference.items():
...     swapped_color_reference[value] = key

>>> swapped_color_reference
{'#8076a3': 'Purple Mountains Majesty',
 '#f9c5bd': 'Misty Mountain Pink',
 '#7c677f': 'Factory Stone Purple',
 '#478559': 'Green Treeline',
 '#161748': 'Purple baseline'}

 
# A dictionary comprehension can also be used to swap entries.
>>> swapped = {value: key for key, value in
               color_reference.items()}
>>> swapped
{'#8076a3': 'Purple Mountains Majesty',
 '#f9c5bd': 'Misty Mountain Pink',
 '#7c677f': 'Factory Stone Purple',
 '#478559': 'Green Treeline',
 '#161748': 'Purple baseline'}

如果 dict 中儲存的值不唯一,在交換鍵與值之前就需要額外的檢查:

# Things become more complicated if there are duplicates in 
# potential key values.This dict is arranged by hex, RGB, and HSL
# keys, but values repeat.
>>> extended_colors = {'#8076a3': 'Purple Mountains Majesty',
                       (128, 118, 163): 'Purple Mountains Majesty',
                       (21, 28, 0, 36): 'Purple Mountains Majesty',
                       '#f9c5bd': 'Misty Mountain Pink',
                       (249, 197, 189): 'Misty Mountain Pink',
                       (0, 21, 24, 2): 'Misty Mountain Pink',
                       '#7c677f': 'Factory Stone Purple',
                       (124, 103, 127): 'Factory Stone Purple',
                       (2, 19, 0, 50): 'Factory Stone Purple',
                       '#478559': 'Green Treeline',
                       (71, 133, 89): 'Green Treeline',
                       (47, 0, 33, 48): 'Green Treeline'}
                                
# New empty dictionary for holding swapped entries.
>>> consolidated_colors = {}

# Iterating over (key, value) pairs using .items()
>>> for key, value in extended_color_reference.items():
...    if value in consolidated_colors: # <--Check if key has already been created.
...        consolidated_colors[value].append(key)
...    else:
...        consolidated_colors[value] = [key]  # <--Create a value list with the former key in it.

>>> consolidated_colors
{'Purple Mountains Majesty': ['#8076a3', (128, 118, 163), (21, 28, 0, 36)],
 'Misty Mountain Pink': ['#f9c5bd', (249, 197, 189), (0, 21, 24, 2)],
 'Factory Stone Purple': ['#7c677f', (124, 103, 127), (2, 19, 0, 50)],
 'Green Treeline': ['#478559', (71, 133, 89), (47, 0, 33, 48)]}  

如果想深入了解字典以及操作字典的方法,官方教學與官方函式庫參考是很棒的起點。

Real Python 與 Finxter 也有非常詳盡的 Python 字典文章。

想了解更多排序的內容,請參閱 Python 文件中的 Sorting HOW TO。

透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 字典方法

練習已鎖定

再解鎖 3 個練習,就能練習 字典方法