开发者

What is the best way to make a shallow copy of a Python dictionary?

开发者 https://www.devze.com 2023-02-02 08:46 出处:网络
Assume we have a simple Python dictionary: dict_ = {\'foo\': 1, \'bar\': 2}开发者_如何学运维 Which is the better way to copy this dictionary?

Assume we have a simple Python dictionary:

dict_ = {'foo': 1, 'bar': 2}开发者_如何学运维

Which is the better way to copy this dictionary?

copy1 = dict(dict_)
copy2 = dict_.copy()

Is there a compelling reason to favour one approach over the other?


I always use the dict constructor: it makes it obvious that you are creating a new dict whereas calling the copy method on an object could be copying anything. Similarly for list I prefer calling the constructor over copying by slicing.

Note that if you use subclasses of dict using the copy method can get confusing:

>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> d['a']
0
>>> d.copy()
defaultdict(<class 'int'>, {'a': 0})
>>> dict(d)
{'a': 0}
>>> 

The copy method of defaultdict gives you another defaultdict, but unless you override copy in a subclass the default action is just to give you a dict:

>>> class MyDict(dict): pass

>>> d = MyDict(a=1)
>>> d
{'a': 1}
>>> type(d)
<class '__main__.MyDict'>
>>> type(d.copy())
<class 'dict'>

That means you have to know about the internal details of a subclass to know what type the copy method will return.


One could favor option #1 (dict(dict_)) because of the principle of least surprise: you can do the same for lists: list(list_), and lists don't have a copy() method.

That said, many good points were raised in the answers. This indicates that there might not be any obviously better solution, and that both are fine, as long as you do what you intend to do (the point about subclassing dict might be crucial, in some codes, for instance). So, I would just choose whatever feels right for your application given the points raised in the responses!


It really depends... on what you actually intend to use it for. In library, you may need to mutate a copy of some dict-like object, and you want a copy that is the same object. Other APIs must have an actual dict, so would create a new dict with the constructor method and use that one. But you lose the actual original type information (and methods) when you do that. But overall, I would prefer the copy() method as it is clear it is a copy of of a dict-like object (not just a dict). That makes it more flexible (duck typing).


The best would be dict_.copy() since the intention is self-descriptive. However, using the dict form you can create a copy with extra keys:

d = dict(a, zoo=1, zar=2)

which is equivalent, but shorter than:

d = a.copy()
d.update(zoo=1, zar=2)


Second one is better because it explicitly shows you are copy'ing.


I don’t like the dict.copy() method:

  • it’s not clear from the name what kind of copy .copy() does
  • subclasses have to overwrite it, or it’s semantic is completely hosed
  • shallow copies can be done by other ways (the general copy.copy() or dict())

Imagine a random class, e.g. Uber. – How would you try to make a copy of u = Uber(...)?

  1. dict(u)
  2. Uber(u)
  3. u.copy()
  4. copy.copy(u)

I would say that number 2. has the highest chances to work —or— to blow up. – Exactly what I want.

0

精彩评论

暂无评论...
验证码 换一张
取 消