制作Python字典的浅表副本的最佳方法是什么?

时间:2011-01-03 09:54:18

标签: python

假设我们有一个简单的Python字典:

dict_ = {'foo': 1, 'bar': 2}

复制此词典的更好方法是什么?

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

是否有令人信服的理由支持一种方法而不是另一种方法?

6 个答案:

答案 0 :(得分:8)

我总是使用dict构造函数:很明显你创建了一个新的dict,而在一个对象上调用copy方法可能会复制任何东西。类似地,对于list,我更喜欢通过切片来调用构造函数而不是复制。

请注意,如果您使用dict方法使用copy的子类会让您感到困惑:

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

copy的{​​{1}}方法为您提供了另一个defaultdict,但除非您在子类中覆盖defaultdict,否则默认操作只是为您提供copy }:

dict

这意味着你必须知道子类的内部细节,才能知道>>> class MyDict(dict): pass >>> d = MyDict(a=1) >>> d {'a': 1} >>> type(d) <class '__main__.MyDict'> >>> type(d.copy()) <class 'dict'> 方法将返回什么类型。

答案 1 :(得分:3)

人们可能会赞成选项#1(dict(dict_)),原因是最不惊讶:您可以对列表执行相同操作:list(list_),列表没有copy()方法

尽管如此,答案中提出了很多好处。这表明可能没有任何明显更好的解决方案,并且两者都很好,只要你做你想做的事情(关于子类化dict的观点可能是至关重要的,例如,一些代码)。因此,我会根据回复中提出的要点选择适合您申请的任何内容!

答案 2 :(得分:3)

这实际上取决于你实际打算用它做什么。在库中,您可能需要改变某些类似dict的对象的副本,并且您需要一个同一个对象的副本。其他API必须具有实际dict,因此将使用构造方法创建新的dict并使用该方法。但是当你这样做时,你会丢失实际的原始类型信息(和方法)。但总的来说,我更喜欢copy()方法,因为很明显它是类似dict的对象(不仅仅是一个字典)的副本。这使它更灵活(鸭子打字)。

答案 3 :(得分:2)

最好的是dict_.copy(),因为意图是自我描述性的。但是,使用dict表单可以创建带有额外键的副本:

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

等同于,但短于:

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

答案 4 :(得分:1)

第二个更好,因为它explicitly显示你是copy'。

答案 5 :(得分:0)

我不喜欢dict.copy()方法:

  • 从名称中不清楚哪种副本.copy()
  • 子类必须覆盖它,或者它的语义是完全软化的
  • 浅层副本可以通过其他方式完成(一般copy.copy()dict()

想象一下随机类,例如Uber。 - 您将如何制作u = Uber(...)的副本?

  1. dict(u)
  2. Uber(u)
  3. u.copy()
  4. copy.copy(u)
  5. 我会说第2号的工作机会最高 - 或者说是爆炸性的。 - 正是我想要的。