如何使用 OrderedDict,一個 Python 有序字典。

商業

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 對象,並在任意位置添加一個新元素。具體來說,這可以在以下流程中完成。

  1. 使用 list() 列出可以通過 items() 方法獲取的視圖對象。
  2. 在列表的 insert() 方法中添加鍵值對的元組 (key, value)
  3. 通過將其傳遞給構造函數 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() 指定要插入的位置作為第一個參數,以及要插入的元素作為第二個參數。

在該示例中,一個新對像被分配給原始變量,並且沒有向原始對象本身添加新元素。

重新排列(重新排序)元素

替換元素的過程與上例相同。

  1. 使用 list() 列出可以通過 items() 方法獲取的視圖對象。
  2. 替換列表中的元素
  3. 通過將其傳遞給構造函數 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)])