字典

字典 在 Python

37 個練習

關於 字典

Python 中的字典(dict)是一種資料結構,會把可雜湊的_鍵_對應到_值_,在其他程式語言裡,它稱為可調整大小的雜湊表、hashmap 或關聯陣列。字典是 Python 唯一內建的對應型態。

keys必須可雜湊,而且在整本字典中獨一無二。鍵的型態可以包含number、str或tuple(由_不可變_值組成),不能包含list、dict或set這類_可變_的資料結構。從 Python 3.7 起,dict的鍵順序保證就是項目插入的順序。

values可以是任何資料型態或結構。值也可以_任意_巢狀,因此可以包含陣列的陣列、子字典,以及其他自訂或複合的資料結構。

給定一個key,字典可以在(平均)常數時間內取出value(與項目數量無關)。相較於在list或array中搜尋某個值(在不知道index位置的情況下),dict會用掉明顯更多的記憶體,但取用速度極快。

當項目集合龐大,而且必須頻繁存取與更新時,字典特別好用。

建立字典

建立字典的方式有很多種,包括:

  • 使用 fromkeys() 類別方法。
  • 使用字典推導式。
  • 透過解包(**)合併兩個字典。
  • 透過|(更新)運算子合併字典。
  • 使用迴圈,逐一將項目加入先前建立好的空dict。

最直接的兩種方法是字典_建構子_和字典_字面值_。

字典建構子

dict()(dict類別的建構子)可以搭配任何由key、value配對組成的可迭代物件使用。也可以用一連串<name>=<value>_引數_來呼叫:

# Passing a list of key,value tuples.
>>> wombat = dict([('name', 'Wombat'),
...              ('speed', 23),
...              ('land_animal', True)])
{'name': 'Wombat', 'speed': 23, 'land_animal': True}


# Using key=value arguments.
>>> bear = dict(name="Black Bear",
...             speed=40,
...             land_animal=True)
{'name': 'Black Bear', 'speed': 40, 'land_animal': True}

dict的說明文件列出了建構子用法的更多變化與選項。

字典字面值

字典也可以直接用_字典字面值_寫成,也就是用大括號({})把key : value配對括起來。包在{}裡的項目也可以分開放在不同行:

>>> whale = {"name": "Blue Whale", 
             "speed": 35, 
             "land_animal": False}
{'name': 'Blue Whale', 'speed': 35, 'land_animal': False}

>>> wombat = {'name': 'Wombat',
              'speed': 23,
              'land_animal': True,
              'color': 'Brindle'}

>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True, 'color': 'Brindle'}

巢狀字典

字典可以任意巢狀:

animals = {
    "Real" : {
        "Winged" : {
            "Sparrow" : {'name': 'sparrow','speed': 12, 'land_animal': True},
            "Kestrel" : {'name': 'kestrel', 'speed': 15, 'land_animal': True}
           },
        "Legged" : {
            "Wombat" : {'name': 'Wombat', 'speed': 23, 'land_animal': True},
            "Black Bear": {'name': 'Black Bear', 'speed': 40, 'land_animal': True},
            "Polecat" : {'name': 'Polecat', 'speed': 15, 'land_animal': True}
           },
        "Other" :  {
            "Whale" : {'name': 'Blue Whale', 'speed': 35, 'land_animal': False},
            "Orca" : {'name': 'Orca', 'speed': 45, 'land_animal': False},
            "Snake" : {'name': 'Python', 'speed': 25, 'land_animal': True}
            }
        },
        
    "Imaginary": {
        "Winged" : {
            "Dragon" : {'name': 'Fire Dragon','speed': 100, 'land_animal': True},
            "Phoenix" : {'name': 'Phoenix', 'speed': 1500, 'land_animal': True}
            },
        "Legged" : {
            "Sphinx" : {'name': 'Sphinx','speed': 10, 'land_animal': True},
            "Minotaur" : {'name': 'Minotaur', 'speed': 5, 'land_animal': True}
            },
        "Other" :  {}
        }
   }

存取dict中的值

你可以用方括號中的_鍵_來存取字典裡的value。如果字典裡沒有這個鍵,就會拋出KeyError:

>>> bear["speed"]
40

>>> bear["color"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'color'

改用get(<key>, <default value>)方法存取項目,就能避開KeyError:

>>> bear.get("color", 'not found')
'not found'

存取巢狀字典的項目

要存取巢狀字典裡的項目,就連續使用方括號。如果指定的鍵不存在,就會拋出平常的 KeyError:

# Using the animals nested dictionary.
>>> animals["Real"]["winged"]["Kestrel"]["speed"]
15

>>> animals["Imaginary"]["winged"]["Kestrel"]["speed"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Kestrel'

要避開KeyError,可以使用.get(),但這些.get()呼叫必須_串接_起來:

# Using the animals nested dictionary.
# Note the use of parenthesis to enable placing the 
# .get() calls on separate lines.
>>> (animals.get("Imaginary", {})
            .get("Legged", {})
            .get("Sphinx", {})
            .get("Color", "I have no idea!"))
'I have no idea!'

修改或新增字典的值

你可以對項目的_鍵_賦值,來修改它的value:

# Assigning the value "Grizzly Bear" to the name key.
>>> bear["name"] = "Grizzly Bear"
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True}

>>> whale["speed"] = 25
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False}

新的key:value配對也可以用同樣的方式_新增_:

# Adding a new "color" key with a new "tawney" value.
>>> bear["color"] = 'tawney'
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True, 'color': 'tawney'}

>>> whale["blowholes"] = 1
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False, 'blowholes': 1}

移除字典項目(pop 與 del)

你可以用<dict>.pop(<key>)方法刪除字典項目。<dict>.pop()會移除(key、value)配對,並回傳value供後續使用。和<dict>.get()一樣,<dict>.pop(<key>)可以接受第二個引數(<dict>.pop(<key>, <default value>)),在找不到該key時回傳。這樣就能避免引發KeyError:

# Using .pop() removes both the key and value, returning the value.
>>> bear.pop("name")
'Grizzly Bear'


# The "name" key is now removed from the dictionary.
# Attempting .pop() a second time will throw a KeyError.
>>> bear.pop("name")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'name'


# Using a default argument with .pop() will 
# prevent a KeyError from a missing key.
>>> bear.pop("name", "Unknown")
'Unknown'

你也可以用del敘述移除一或多個項目。如果要移除的項目不在字典裡,就會引發KeyError:

>>> wombat = {'name': 'Wombat',
              'speed': 23,
              'land_animal': True,
              'color': 'Brindle',
              'talent': 'Singing',
              'size': 'small'}

# Remove a single entry from the dictionary.
>>> del wombat["color"]
>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True, 'talent': 'Singing', 'size': 'small'}


# Remove multiple entries from the dictionary.
>>> del wombat["talent"], wombat["size"]
>>> wombat
{'name': 'Wombat', 'speed': 23, 'land_animal': True}


# Attempting a deletion of a non-existent key raises a KeyError
>>> del wombat["number_of_legs"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'number_of_legs'

走訪/疊代字典

使用for item in dict或while item走訪字典時,預設會疊代_鍵_。在同一個迴圈裡,你可以用_方括號_存取_值_:

>>> for key in bear:
...     print((key, bear[key])) # <--This prints a tuple of (key, value).
('name', 'Black Bear')
('speed', 40)
('land_animal', True)

你也可以使用.items()方法,它會回傳(key、value)元組:

# dict.items() forms (key, value tuples) that can be 
# unpacked and iterated over.
>>> for key, value in whale.items():
...     print(key, ":", value)
name : Blue Whale
speed : 25
land_animal : False
blowholes : 1

同樣地,.keys()會回傳keys,.values()會回傳values。

如果想深入了解 Python 的字典,官方說明文件是很棒的起點,你也可以看看 W3-Schools 的教學。

擴充字典功能:collections 模組

collections模組為 Python 標準的集合類資料型態(dict、set、list、tuple)增添了特殊功能。其中三個最實用的字典類別是:

  • Counter會自動計數項目,並以項目為鍵、計數為值,用dict回傳。
  • OrderedDict有專門用來安排字典項目順序的方法。
  • defaultdict使用工廠方法,在嘗試取出或指定字典項目卻找不到key時,設定一個預設值。
透過 GitHub 編輯 連結會在新視窗或分頁中開啟

學習 字典

練習已鎖定

再解鎖 4 個練習,就能練習 字典