Issue
In Python there are various ways to create a shallow copy of a dict
: there's the dict
constructor, the dict.copy
method, and the function copy
from the copy
module:
>>> 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]}
From the above example, all these 3 methods seem to achieve the same result. Is there a difference in their functionality and should one of them be preferred over the others?
A similar question could be asked for lists, where we can use l2 = list(l1)
, l2 = l1.copy()
, l2 = copy.copy(l1)
or l2 = l1[:]
.
Solution
Short answer: they are functionally equivalent.
No differences between the functions are described in the documentation. Examining the source, each will use the same function (dict_merge
) in many cases.
Looking at the source of the copy
module, copy.copy
calls dict.copy
(as well as a few other type-specific copy methods, such as list.copy
, for values of those types). Thus the only difference between copy(d)
and d.copy()
is that a variable must be known to have a copy
method to use the latter.
The help doc for dict(d)
notes:
dict(mapping) -> new dictionary initialized from a mapping object's (key, value) pairs
The constructor works on all mapping types, not just dicts. This won't cause functional differences, but could impact performance due to handling a more general case. However, examining the source shows the constructor calls dict_merge
to handle copying the data, which handles dict
s specially, so the underlying function can apply case-specific optimizations.
dict.copy
calls PyDict_copy
, which handles a few special cases itself but calls dict_merge
if none of those apply.
In summary: in terms of functionality, use any of them. If a value is known to have a copy
method (e.g. it's known to be a dict
), d.copy()
will likely be the most performant option. If the exact type of a value isn't known but it's known to be a mapping type, use copy.copy()
or dict()
. If nothing is known about the type, use copy.copy()
.
Copy operations on list
should be similar, though using a slice (l1[:]
) may not use the same underlying function.
Answered By - outis
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.