Python3中collections.OrderedDict介绍

x33g5p2x  于2021-12-25 转载在 Python  
字(3.6k)|赞(0)|评价(0)|浏览(172)

    Python3中的collections模块实现了特定目标的容器,以提供Python标准内建容器dict、list、set和tuple的替代选择,包括namedtuple、deque、ChainMap、Counter、OrderedDict、defaultdict、UserDict、UserList、UserString。这里介绍下OrderedDict,它继承自dict,返回dict子类的实例,实现在 https://github.com/python/cpython/blob/3.10/Lib/collections/init.py

    OrderedDict是dict子类,OrderedDict会记住item插入的顺序。常规dict不跟踪插入顺序,迭代它会以任意顺序给出值(Python 3.7之前的版本会这样)。Python 3.7开始,dict****的插入顺序也得到保证

    如果某个key的值发生变化,key在OrderedDict中的位置保持不变。

    删除和重新插入相同的key会将它push到后面作为OrderedDict,但是,保持插入的顺序。

    OrderedDict比dict中多的函数为move_to_end。此函数将现有key移动到OrderedDict的任一端。如果参数last为True(默认值),则将item移至末尾;如果last为False,则移至开头。如果key不存在,则触发KeyError。

    OrderedDict与dict差异:

    (1).dict被设计为非常擅长映射操作(map operation),跟踪插入顺序是次要的。

    (2).OrderedDict旨在擅长重新排序操作(reorder operation),空间效率、迭代速度和更新操作的性能是次要的。

    (3).在算法上,OrderedDict可以比dict更好地处理频繁的重新排序操作。

    (4).OrderedDict的popitem函数具有不同的签名,它接受一个可选参数来指定pop的pair(key, value)是LIFO order(当last为True时)还是FIFO order。

    (5).OrderedDict的move_to_end函数可以有效地将item移动到任一端。

    (6).OrderedDict对象与常规dict比较,对顺序不敏感;但是OrderedDict对象之间的相等性判断是顺序敏感的。

   测试代码如下:

from collections import OrderedDict

var = 2
if var == 1:
    # reference: https://www.geeksforgeeks.org/ordereddict-in-python/
    # 注:在Python 3.7.11中,多次执行以下测试代码,dict和OrderedDict的输出结果始终相同
    # 从python 3.7开始,python dict的插入顺序是有保证的
    print("This is a dict:")
    d = {}
    d["a"] = 1; d["b"] = 2; d["c"] = 3; d["d"] = 4
    for key, value in d.items():
        print(key, value, end=",")

    d["c"] = 5; print("")
    for key, value in d.items():
        print(key, value, end=",")

    d.pop("c"); print("")
    for key, value in d.items():
        print(key, value, end=",")

    d["c"] = 3; print("")
    for key, value in d.items():
        print(key, value, end=",")

    print("\nThis is an Ordered Dict:")
    od = OrderedDict()
    od["a"] = 1; od["b"] = 2; od["c"] = 3; od["d"] = 4
    for key, value in od.items():
        print(key, value, end=",")

    # 如果某个key的值发生变化,key在OrderedDict中的位置保持不变
    od["c"] = 5; print("")
    for key, value in od.items():
        print(key, value, end=",")

    # 删除和重新插入相同的key会将它push到后面作为OrderedDcit,但是,保持插入的顺序
    od.pop("c"); print("")
    for key, value in od.items():
        print(key, value, end=",")

    od["c"] = 3; print("")
    for key, value in od.items():
        print(key, value, end=",")
    print("")
elif var == 2:
    od = OrderedDict()
    print(isinstance(od, OrderedDict)) # True
    print(isinstance(od, dict)) # True

    od["a"] = 1; od["b"] = 2; od["c"] = 3; od["d"] = 4
    # popitem: 返回一个(key, value)键值对.如果last为True,则按LIFO后进先出的顺序返回键值对,否则就按FIFO先进先出的顺序返回键值对
    print(od.popitem(last=True)) # ('d', 4)
    print(od.popitem(last=False)) # ('a', 1)

    od["e"] = 5; od["f"] = 6
    for key, value in od.items():
        print(key, value, end=",") # b 2,c 3,e 5,f 6,
    print("")

    # move_to_end: 将现有key移动到OrderedDict的任一端.如果last为True(默认值),则将item移至末尾;如果last为False,则移至开头;如果key不存在,则触发KeyError
    od.move_to_end("c", last=True)
    for key, value in od.items():
        print(key, value, end=",") # b 2,e 5,f 6,c 3,
    print("")

    od.move_to_end("c", last=False)
    for key, value in od.items():
        print(key, value, end=",") # c 3,b 2,e 5,f 6,
    print("")

    # OrderedDict对象与常规dict比较,对顺序不敏感
    d1 = {"c":3, "b":2, "e":5, "f":6}; print(od == d1) # True
    d2 = {"b":2, "e":5, "f":6, "c":3}; print(od == d2) # True
    print(d1 == d2) # True

    # ​OrderedDict对象之间的相等性判断是顺序敏感的
    od2 = OrderedDict()
    od2["c"] = 3; od2["b"] = 2; od2["e"] = 5; od2["f"] = 6; print(od == od2) # True
    od3 = OrderedDict()
    od3["c"] = 3; od3["b"] = 2; od3["f"] = 6; od3["e"] = 5; print(od3 == od2) # False

print("test finish")

   GitHubhttps://github.com/fengbingchun/Python_Test

相关文章