有序字典的深度复制是否可以保留其顺序?

问题描述 投票:4回答:3

我做了一个小程序并测试它确实保留了订单。但是,我仍然希望确保deepcopy能够做到这一点。

import copy
import collections

a_dict = collections.OrderedDict()
a_dict['m'] = 10
a_dict['u'] = 15
a_dict['c'] = 5
a_dict['h'] = 25
a_dict['a'] = 55
a_dict['s'] = 30

print(a_dict)

other_dict = copy.deepcopy(a_dict)

other_dict['g'] = 75
other_dict['r'] = 35

print(other_dict)

这个程序的输出是

OrderedDict([('m', 10), ('u', 15), ('c', 5), ('h', 25), ('a', 55), ('s', 30)])
OrderedDict([('m', 10), ('u', 15), ('c', 5), ('h', 25), ('a', 55), ('s', 30), ('g', 75), ('r', 35)])
python deep-copy ordereddictionary
3个回答
1
投票

在CPython中,似乎保留了订单。我从检查deepcopy的实施中得出了这个结论。在这种情况下,它会在你的__reduce_ex__对象上找到用于酸洗的__reduce__OrderedDict方法:

(Qazxswpoi)

https://github.com/python/cpython/blob/master/Lib/copy.py#L159-L161

那些返回用于构造的def deepcopy(x, memo=None, _nil=[]): ... reductor = getattr(x, "__reduce_ex__", None) if reductor is not None: rv = reductor(4) else: reductor = getattr(x, "__reduce__", None) if reductor: rv = reductor() 对象,因此将保留顺序:

odict_iterator

4
投票

通过>>> a = {} >>> b = collections.OrderedDict() >>> a['a'] = 1 >>> b['a'] = 1 >>> a.__reduce_ex__(4) (<function __newobj__ at 0x10471a158>, (<class 'dict'>,), None, None, <dict_itemiterator object at 0x104b5d958>) >>> a.__reduce__() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/opt/local/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/copyreg.py", line 65, in _reduce_ex raise TypeError("can't pickle %s objects" % base.__name__) TypeError: can't pickle dict objects >>> b.__reduce_ex__(4) (<class 'collections.OrderedDict'>, (), None, None, <odict_iterator object at 0x104c02d58>) >>> b.__reduce__() (<class 'collections.OrderedDict'>, (), None, None, <odict_iterator object at 0x104c5c780>) >>> 正确实现复制应该产生一个与原始对象相同的对象(假设完全定义了相等性)。虽然没有,但是没有关于copy.deepcopyOrderedDict的明确的文件保证,如果copy.deepcopy的顺序在副本中发生变化,它将不等于原始的OrderedDict,这将大大违反复制相等的期望。

没有坚定的保证可以真正给出,因为密钥或值的OrderedDict方法可以做一些真正可怕的事情(例如修改源__deepcopy__),但除了病态情况,你可以依靠OrderedDict来保持排序。


0
投票

对象的深度复制应该返回相同类型的对象。所以,作为副本返回的有序指令应该仍然有序?

编辑 - 这不是完全正确的答案。请看下面Greg的评论。

© www.soinside.com 2019 - 2024. All rights reserved.