如何创建未链接到原始对象的python对象的副本?

时间:2013-03-22 20:00:25

标签: python object dictionary

(使用Python 2.7)

我正在尝试创建模板对象的复制品,以便稍后填写。为简单起见,我尝试这样做:

template={'thing1':'','thing2':'','thing3':''}
for number in some_list:
    pile[number]=template

但后来当我这样做时:

pile[1]['thing1']='blahblah'

它还会导致:

print pile[2]['thing1']
'blahblah'
print template['thing1']
'blahblah'

我想要的是

pile[1]['thing1']='blahblah'

单独留堆[2],以便

print pile[2]['thing1']
''

我知道问题是当我说

pile[number]=template

表示桩[1]是IS模板,桩[2]是IS模板。 (这个我今天才完全意识到这一点......而且我多次大声重复它,因为实现及其影响慢慢沉没......这就是python 的工作方式,呃?我觉得我刚加入了蟒蛇俱乐部。我从MATLAB开始,所以不要对我太粗暴。)

所以我想可能有两种方法可以解决这个问题 - 一种方法涉及某些未与原始对象相关联的对象的复制,或类似的东西,并且可能非常简单明了。也许还有另一种方法可以做到特定于dicts,比如初始化键或其他东西。我最感兴趣的是第一种答案,因为这有助于完善我对python 如何工作的理解,但第二种答案也会很好。谢谢:))

2 个答案:

答案 0 :(得分:2)

制作字典浅表副本的最简单方法是使用dict的copy方法:

In [1]: template = {'thing1': '', 'thing2': '', 'thing3': ''}

In [2]: apile = template.copy()

In [3]: apile['thing1'] = 1

In [4]: apile
Out[4]: {'thing1': 1, 'thing2': '', 'thing3': ''}

In [5]: template
Out[5]: {'thing1': '', 'thing2': '', 'thing3': ''}

要制作列表的浅表副本,您可以获取整个列表的一部分:

copied_list = original_list[:]

如果你需要克隆其他东西,或者你需要深刻的dicts字典(或dicts列表或其他可变对象),你应该使用copy模块:{{3 }}

copy.copy(x)
  

返回x的浅表副本。

copy.deepcopy(x)
  

返回x的深层副本。

浅层复制和深层复制之间的区别仅与复合对象(包含其他对象的对象,如列表或类实例)相关:

  • 浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。
  • 深层复制构造一个新的复合对象,然后以递归方式将副本插入到原始对象中找到的对象。

关于你的第二种方式:当然,你可以用另一个词典创建一个词典,它将是一个副本:

In [23]: p = dict(template)

In [24]: p['thing1'] = 1

In [25]: template
Out[25]: {'thing1': '', 'thing2': '', 'thing3': ''}

In [26]: p
Out[26]: {'thing1': 1, 'thing2': '', 'thing3': ''}

答案 1 :(得分:2)

这是我最初的解决方案

import copy

template = {1:''}
d = {}

for n in xrange(10):
    d[n] = copy.deepcopy(template)

然而我更喜欢帕维尔。