字典
April 11, 2022字典(dict)物件是儲存鍵(key)/值(value)對應的物件,為 dict
的實例。
dict 操作
直接示範如何以實字建立 dict
物件:
>>> passwords = {'Justin' : 123456, 'caterpillar' : 933933}
>>> passwords['Justin']
123456
>>> passwords['caterpillar']
933933
>>> passwords['Hamimi'] = 970221
>>> passwords
{'caterpillar': 933933, 'Hamimi': 970221, 'Justin': 123456}
>>> passwords['Hamimi']
970221
>>> del passwords['caterpillar']
>>> passwords
{'Hamimi': 970221, 'Justin': 123456}
>>>
建立 dict
時,作為鍵的元素必須是 hashable,也就是實作了 __hash__
與 __eq__
方法,鍵是用來與值物件對應,指定鍵物件取得值物件時是使用 []
運算子,如果要刪除某個鍵/值,則可以使用 del
。
直接使用 []
指定鍵要取得值時,若 dict
沒有該鍵的存在,會丟出 KeyError
。可以使用 in
來測試鍵是否存在於 dict
中。例如:
>>> passwords['caterpillar']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'caterpillar'
>>> if 'caterpillar' in passwords:
... print(passwords['Justin'])
... else:
... print(None)
...
None
>>> print(passwords.get('caterpillar'))
None
>>> print(passwords.get('caterpillar', 'NO_PASSWORD'))
NO_PASSWORD
>>>
上例中,get
方法指定的鍵若不存在,預設會傳回 None
而不是丟出錯誤,get
可以指定預設值,在指定的鍵不存在時就傳回預設值。
可以使用 update
合併 dict
,使用 pop
方法將對應的鍵/值取出並從 dict
移除。例如:
>>> passwords
{'Hamimi': 970221, 'Justin': 123456}
>>> passwords.update({'Momor' : 670723})
>>> passwords
{'Hamimi': 970221, 'Justin': 123456, 'Momor': 670723}
>>> passwords.pop('Justin')
123456
>>> passwords
{'Hamimi': 970221, 'Momor': 670723}
Python 3.9 以後,可以透過 |
來更簡單地合併 dict
,若作為運算元的 dict
有重複鍵值,傳回的 dict
會使用 |
右運算元的鍵值,例如:
>>> passwords = {'Hamimi': 970221, 'Justin': 123456}
>>> passwords | {'Momor' : 670723}
{'Hamimi': 970221, 'Justin': 123456, 'Momor': 670723}
>>> d1 = {'a': 10, 'b': 20}
>>> d2 = {'b': 30, 'c': 40}
>>> r = d1 | d2
>>> r
{'a': 10, 'b': 30, 'c': 40}
>>>
鍵/值
如果要取得 dict
中全部的鍵/值,則可以使用 items
方法,這會傳回 dict_items
物件,當中是以 tuple
儲存每組鍵/值。
如果只是要取得全部的鍵,可以使用 keys
方法,這會傳回 dict_keys
物件;如果只是要取得全部的值,可以使用 values
方法,這會傳回 dict_values
物件。例如:
>>> for person in passwords:
... print(passwords[person])
...
970221
670723
>>> passwords.items()
dict_items([('Hamimi', 970221), ('Momor', 670723)])
>>> for item in passwords.items():
... print(item)
...
('Hamimi', 970221)
('Momor', 670723)
>>> passwords.keys()
dict_keys(['Hamimi', 'Momor'])
>>> for key in passwords.keys():
... print(key)
...
Hamimi
Momor
>>> list(passwords.keys())
['Hamimi', 'Momor']
>>> passwords.values()
dict_values([970221, 670723])
>>> for value in passwords.values():
... print(value)
...
970221
670723
>>> list(passwords.values())
[970221, 670723]
>>>
在 Python 3.5 以前,不保證鍵的順序,Python 3.6 開始,會以字面值時每對鍵值的撰寫順序,或者 dict
的安插順序來作為 items
、keys
、values
的迭代順序,並且這在 Python 3.7 成為正式特性。
在 Python 3.7 以後,要小心使用這個特性,務必確認你操作的是 dict
實例,而不是長得像 dict
的實例;在 Python 3.7 之前,若要保證順序,可以使用 collections.OrderedDict
。
items
、keys
、values
為什麼不直接傳回 list
呢?若 dict
中有許多鍵值,相較於建立一個夠長的 list
來儲存這些元素,items
、keys
、values
的作法比較經濟,因為 dict_items
、dict_keys
、dict_values
傳回後,尚未實際取得 dict
的對應鍵值,只有在真正需要下個元素時,才會進行相關運算,這樣的特性稱為惰性求值(Lazy evaluation)。
items
、keys
傳回的物件具有集合的行為,可以與集合物件進行運算,values
則否,因為值不一定是唯一(不同的鍵可能有相同的值)。例如:
>>> passwords.items() | {'x', 'y'}
{'y', ('Momor', 670723), 'x', ('Hamimi', 970221)}
>>> passwords.keys() | {'x', 'y'}
{'y', 'x', 'Hamimi', 'Momor'}
>>> passwords.values() | {'x', 'y'}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'dict_values' and 'set'
>>>
除了實字表示方式之外,也可以使用 dict
建立實例。例如:
>>> passwords = dict(justin = 123456, momor = 670723, hamimi = 970221)
>>> passwords
{'hamimi': 970221, 'justin': 123456, 'momor': 670723}
>>> passwords = dict([('justin', 123456), ('momor', 670723), ('hamimi', 970221)])
>>> passwords
{'hamimi': 970221, 'justin': 123456, 'momor': 670723}
>>> dict.fromkeys(['Justin', 'momor'], 'NEED_TO_CHANGE')
{'Justin': 'NEED_TO_CHANGE', 'momor': 'NEED_TO_CHANGE'}
>>>