复制字典和列表的不同方法
Different methods of copying dicts and lists
在 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]}
从上面的例子来看,这3种方法似乎都达到了相同的结果。它们的功能是否存在差异?是否应该优先选择其中之一?
对于列表,我们可以使用 l2 = list(l1)
、l2 = l1.copy()
、l2 = copy.copy(l1)
或 l2 = l1[:]
.
来询问类似的问题
如果您希望 dict
变量中发生的任何更新发生在另一个变量上,您可以使用:
dictb=dicta
对可迭代/复合对象(例如列表)或 non-iterable 元素的任何更新都会发生在另一个上。
如果您希望 non-iterable 元素保持完整,您可以复制 element-by-element dict
的内容,或者使用方法 copy()
dictb= dicta.copy()
或
dictb=copy(dicta)
最后,如果您不想在复制的 dict
中更新两者,请使用 deepcopy()
from copy import deepcopy
dictb=deepcopy(dicta)
至于速度dicta.copy()
最快,然后dict(dicta)
,然后copy(dicta)
简答:它们在功能上是等价的。
文档中没有描述函数之间的差异。检查来源,在许多情况下每个人都会使用相同的功能(dict_merge
)。
查看 copy
模块的源代码,copy.copy
调用 dict.copy
(以及其他一些 type-specific 复制方法,例如 list.copy
,对于那些类型的值)。因此 copy(d)
和 d.copy()
之间的唯一区别是必须知道变量具有 copy
方法才能使用后者。
dict(d)
注释的帮助文档:
dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs
构造函数适用于所有映射类型,而不仅仅是字典。这不会导致功能差异,但可能会因处理更一般的情况而影响性能。但是,检查源代码显示构造函数调用 dict_merge
来处理复制数据,它专门处理 dict
,因此底层函数可以应用 case-specific 优化。
dict.copy
调用 PyDict_copy
,它自己处理一些特殊情况,但如果有 none 个适用,则调用 dict_merge
。
总结:就功能而言,使用其中任何一个。如果已知某个值具有 copy
方法(例如,已知它是 dict
),则 d.copy()
可能是性能最高的选项。如果不知道值的确切类型但已知它是映射类型,请使用 copy.copy()
或 dict()
。如果对类型一无所知,请使用 copy.copy()
.
list
上的复制操作应该类似,但使用切片 (l1[:]
) 可能不会使用相同的底层函数。
在 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]}
从上面的例子来看,这3种方法似乎都达到了相同的结果。它们的功能是否存在差异?是否应该优先选择其中之一?
对于列表,我们可以使用 l2 = list(l1)
、l2 = l1.copy()
、l2 = copy.copy(l1)
或 l2 = l1[:]
.
如果您希望 dict
变量中发生的任何更新发生在另一个变量上,您可以使用:
dictb=dicta
对可迭代/复合对象(例如列表)或 non-iterable 元素的任何更新都会发生在另一个上。
如果您希望 non-iterable 元素保持完整,您可以复制 element-by-element dict
的内容,或者使用方法 copy()
dictb= dicta.copy()
或
dictb=copy(dicta)
最后,如果您不想在复制的 dict
中更新两者,请使用 deepcopy()
from copy import deepcopy
dictb=deepcopy(dicta)
至于速度dicta.copy()
最快,然后dict(dicta)
,然后copy(dicta)
简答:它们在功能上是等价的。
文档中没有描述函数之间的差异。检查来源,在许多情况下每个人都会使用相同的功能(dict_merge
)。
查看 copy
模块的源代码,copy.copy
调用 dict.copy
(以及其他一些 type-specific 复制方法,例如 list.copy
,对于那些类型的值)。因此 copy(d)
和 d.copy()
之间的唯一区别是必须知道变量具有 copy
方法才能使用后者。
dict(d)
注释的帮助文档:
dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs
构造函数适用于所有映射类型,而不仅仅是字典。这不会导致功能差异,但可能会因处理更一般的情况而影响性能。但是,检查源代码显示构造函数调用 dict_merge
来处理复制数据,它专门处理 dict
,因此底层函数可以应用 case-specific 优化。
dict.copy
调用 PyDict_copy
,它自己处理一些特殊情况,但如果有 none 个适用,则调用 dict_merge
。
总结:就功能而言,使用其中任何一个。如果已知某个值具有 copy
方法(例如,已知它是 dict
),则 d.copy()
可能是性能最高的选项。如果不知道值的确切类型但已知它是映射类型,请使用 copy.copy()
或 dict()
。如果对类型一无所知,请使用 copy.copy()
.
list
上的复制操作应该类似,但使用切片 (l1[:]
) 可能不会使用相同的底层函数。