Python 字典(dict 類型的對象)不保留元素的順序; CPython 從 3.6 開始就這樣做了,但在其他實現中它依賴於實現並且不確定;語言規範從 3.7 開始保留了順序。
OrderedDict 在標準庫的 collections 模塊中作為保留順序的字典提供。使用這個是安全的。
導入集合模塊。它包含在標準庫中,不需要安裝。
import collections
如果您編寫以下內容,則可以省略集合。在下面的例子中。
from collections import OrderedDict
下面是關於如何使用 OrderedDict 的說明。
- 創建 OrderedDict 對象
- OrderedDict 是 dict 的子類
- 將元素移動到開頭或結尾
- 在任意位置添加一個新元素。
- 重新排列(重新排序)元素
- 按鍵或值對元素進行排序
創建 OrderedDict 對象
構造函數 collections.OrderedDict() 可用於創建 OrderedDict 對象。
創建一個空的 OrderedDict 對象並添加值。
od = collections.OrderedDict()
od['k1'] = 1
od['k2'] = 2
od['k3'] = 3
print(od)
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
也可以為構造函數指定參數。
您可以使用關鍵字參數、鍵值對序列(例如元組 (key, value))等。後者可以是列表或元組,只要是鍵值對即可。
print(collections.OrderedDict(k1=1, k2=2, k3=3))
print(collections.OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)]))
print(collections.OrderedDict((['k1', 1], ['k2', 2], ['k3', 3])))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
在 3.5 版之前,關鍵字參數的順序沒有保留,但從 3.6 版開始,它現在被保留了。
在 3.6 版更改:隨著 PEP 468 的接受,OrderedDict 構造函數的順序和傳遞給 update() 方法的關鍵字參數被保留。
collections — Container datatypes — Python 3.10.0 Documentation
普通字典(dict 類型對象)也可以傳遞給構造函數,但是在 dict 類型不保留順序的實現的情況下,從它生成的 OrderedDict 也不會保留順序。
print(collections.OrderedDict({'k1': 1, 'k2': 2, 'k3': 3}))
# OrderedDict([('k1', 1), ('k2', 2), ('k3', 3)])
OrderedDict 是 dict 的子類
OrderedDict 是 dict 的子類。
print(issubclass(collections.OrderedDict, dict))
# True
OrderedDict也有和dict一樣的方法,獲取、改變、添加、刪除元素的方法和dict一樣。
print(od['k1'])
# 1
od['k2'] = 200
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
od.update(k4=4, k5=5)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('k4', 4), ('k5', 5)])
del od['k4'], od['k5']
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
有關詳細信息,請參閱以下文章。
將元素移動到開頭或結尾
您可以使用 OrderedDict 自己的方法 move_to_end() 將元素移動到開頭或結尾。
指定鍵作為第一個參數。默認是移到末尾,但如果最後一個參數為 false,則將移到開頭。
od.move_to_end('k1')
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1)])
od.move_to_end('k1', False)
print(od)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3)])
在任意位置添加一個新元素。
可以創建一個新的 OrderedDict 對象,並在任意位置添加一個新元素。具體來說,這可以在以下流程中完成。
- 使用 list() 列出可以通過 items() 方法獲取的視圖對象。
- 在列表的 insert() 方法中添加鍵值對的元組 (key, value)
- 通過將其傳遞給構造函數 collections.OrderedDict() 來創建一個新對象
l = list(od.items())
print(l)
# [('k1', 1), ('k2', 200), ('k3', 3)]
l.insert(1, ('kx', -1))
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)])
insert() 指定要插入的位置作為第一個參數,以及要插入的元素作為第二個參數。
在該示例中,一個新對像被分配給原始變量,並且沒有向原始對象本身添加新元素。
重新排列(重新排序)元素
替換元素的過程與上例相同。
- 使用 list() 列出可以通過 items() 方法獲取的視圖對象。
- 替換列表中的元素
- 通過將其傳遞給構造函數 collections.OrderedDict() 來創建一個新對象
l = list(od.items())
print(l)
# [('k1', 1), ('kx', -1), ('k2', 200), ('k3', 3)]
l[0], l[2] = l[2], l[0]
print(l)
# [('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('kx', -1), ('k1', 1), ('k3', 3)])
如果要指定鍵並替換它,請使用 index() 方法從鍵列表中獲取索引(位置),如下所示。
l = list(od.items())
k = list(od.keys())
print(k)
# ['k2', 'kx', 'k1', 'k3']
print(k.index('kx'))
# 1
l[k.index('kx')], l[k.index('k3')] = l[k.index('k3')], l[k.index('kx')]
print(l)
# [('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)]
od = collections.OrderedDict(l)
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])
按鍵或值對元素進行排序
根據可以通過items()方法獲取的視圖對象,創建一個有序鍵值對的元組(key, value)列表,傳遞給構造函數collections.OrderedDict()創建一個新的對象。
排序是通過指定一個匿名函數(lambda 表達式)來執行的,該函數從元組 (key, value) 返回一個鍵或值作為內置函數 sorted() 的參數鍵。
如果要顛倒順序,請將 sorted() 的 reverse 參數設置為 true。
print(od)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])
od_sorted_key = collections.OrderedDict(
sorted(od.items(), key=lambda x: x[0])
)
print(od_sorted_key)
# OrderedDict([('k1', 1), ('k2', 200), ('k3', 3), ('kx', -1)])
od_sorted_value = collections.OrderedDict(
sorted(od.items(), key=lambda x: x[1], reverse=True)
)
print(od_sorted_value)
# OrderedDict([('k2', 200), ('k3', 3), ('k1', 1), ('kx', -1)])