2

(使用 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'

让 pile[2] 一个人呆着,这样

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

我知道问题是当我说

pile[number]=template

这意味着 pile[1] 是模板,而 pile[2] 是模板。(我今天才完全意识到这一点,而我正在研究这个......我对自己重复了好几次,因为实现和它的含义慢慢地沉没了......这就是 python 的工作原理,嗯?我觉得我刚刚加入python 俱乐部。我是从 MATLAB 开始的,所以不要对我太粗鲁。)

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

4

2 回答 2

3

制作字典的浅拷贝最简单的方法是使用 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[:]

 

如果你需要克隆其他东西,或者如果你需要一个字典的深层副本(或字典列表,或其他可变对象),你应该使用copy模块:http ://docs.python.org/2 /图书馆/copy.html

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': ''}
于 2013-03-22T20:03:28.743 回答
2

这是我最初的解决方案

import copy

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

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

但是我更喜欢Pavel。

于 2013-03-22T20:05:19.783 回答