Home > OS >  Different methods of copying dicts and lists
Different methods of copying dicts and lists

Time:05-09

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[:].

CodePudding user response:

If you want any update occurring in the dict variable to happen to the other one you can use:

dictb=dicta

Any update to an iterable / compound object(e.g. a list) or a non-iterable element will happen to the other.

If you want the non-iterable element to stay intact, you can either copy the element-by-element the content of the dict, or use the method copy()

dictb= dicta.copy()

or

dictb=copy(dicta)

Finally, if you want neither to be updated in the copied dict use deepcopy()

from copy import deepcopy
dictb=deepcopy(dicta)

As for the speed dicta.copy() is the fastest, then dict(dicta), then copy(dicta)

CodePudding user response:

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 dicts 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.

  • Related