在Python中,有多种方法可以创建dict
的浅副本:dict
构造函数、dict.copy
方法和copy
模块中的函数copy
:
>>> a = {'a':3, 'b': [1,2,3]}
>>> b = dict(a)
>>> c = a.copy()
>>> from copy import copy
>>> d = copy(a)
>>> a['a'] = 2
>>> a['b'].append(4)
>>> b
{'a': 3, 'b': [1, 2, 3, 4]}
>>> c
{'a': 3, 'b': [1, 2, 3, 4]}
>>> d
{'a': 3, 'b': [1, 2, 3, 4]}
>>> a
{'a': 2, 'b': [1, 2, 3, 4]}
从上面的例子来看,这三种方法似乎都达到了相同的结果。它们的功能有什么不同吗?其中一个应该优先于其他吗?
对于列表,也可以提出类似的问题,我们可以使用l2 = list(l1)
、l2 = l1.copy()
、l2 = copy.copy(l1)
或l2 = l1[:]
。
简单回答:它们在功能上是等效的。
文档中没有描述这些功能之间的差异。检查源,在许多情况下,每个源都将使用相同的函数(dict_merge
)。
从copy
模块的源代码来看,copy.copy
调用dict.copy
(以及一些其他类型特定的复制方法,如list.copy
,用于这些类型的值)。因此,copy(d)
和d.copy()
之间的唯一区别是,必须已知变量具有使用后者的copy
方法。
dict(d)
的帮助文档注释:
dict(映射)->从映射对象(键、值)对初始化的新字典
构造函数适用于所有映射类型,而不仅仅是dict。这不会导致功能差异,但由于处理更一般的情况,可能会影响性能。然而,检查源代码显示构造函数调用dict_merge
来处理数据复制,而CCD_19专门处理dict
s,因此底层函数可以应用特定于具体情况的优化。
dict.copy
调用PyDict_copy
,后者本身处理一些特殊情况,但如果这些情况都不适用,则调用dict_merge
。
总之:就功能而言,可以使用它们中的任何一个。如果已知某个值具有copy
方法(例如,已知其为dict
),则d.copy()
可能是性能最高的选项。如果值的确切类型未知,但已知它是映射类型,请使用copy.copy()
或dict()
。如果对类型一无所知,请使用copy.copy()
。
list
上的复制操作应该类似,尽管使用切片(l1[:]
)可能不使用相同的底层函数。
如果您希望dict
变量中发生的任何更新发生在另一个变量上,您可以使用:
dictb=dicta
对可迭代/复合对象(例如列表)或不可迭代元素的任何更新都会发生在另一个对象上。
如果您希望不可迭代的元素保持不变,您可以逐个元素复制dict
的内容,或者使用方法copy()
dictb= dicta.copy()
或
dictb=copy(dicta)
最后,如果您不想在复制的dict
中更新,请使用deepcopy()
from copy import deepcopy
dictb=deepcopy(dicta)
至于速度,dicta.copy()
最快,然后是dict(dicta)
,然后是CCD 39