当我将一个字典赋值给另一个变量时,为什么Python会更新两个字典?

3

在使用字典时如何避免以下问题

a={'b':1}
c=a
c.update({'b':2})
print a # {'b':2}
print c # {'b':2}

这里的'a'和'b'指向同一内存位置。因此,对'a'的更改会反映在'b'中。 打印(id(a), id(b))并查看它们是否具有相同的id。 - Manjunath
4个回答

7

通过使用字典的copy方法。就像这样:

>>> a = {'b': 1}
>>> c = a.copy()
>>> c.update({'b': 2})
>>> print a
{'b': 1}
>>> print c
{'b': 2}
>>> 

请注意,这是一个浅拷贝。因此,如果您的字典中有可变对象(字典、列表等),它将复制对这些对象的引用。在这种情况下,您应该使用copy.deepcopy。以下是示例:
>>> import copy
>>> a = {'b': {'g': 4}}
>>> c = copy.deepcopy(a)
>>> c['b'].update({'g': 15})
>>> print a
{'b': {'g': 4}}
>>> print c
{'b': {'g': 15}}

我有一个类似于a={'b':'{"g": 4}'}的东西。在这种情况下,我能否只使用.copy()? - Rajeev
不,a['b'] 和 c['b'] 将引用同一个目录,需要使用 deepcopy()。 - RemcoGerlich

2

显然,你的问题已得到答复。但在这里有一点有帮助的是纠正你的思维模式。

在Python中,变量不是“存储”值,而是“命名”值。请查看这篇文章,了解雕像指向酒店的例子。

快速简单地检查是否引用了相同的对象的方法是打印变量的ID:

>>> a = {}
>>> b = a
>>> print(id(a), id(b))
12345 12345

0

0

变量ac都指向同一个字典对象,因此如果您通过变量c对其进行更改,则底层字典对象会更改。由于a指向相同的对象,因此这些更改也将从那里可见。

如果您想让ac引用彼此独立的字典,则需要复制字典,以便实际收到两个单独的对象。您可以使用dict.copy来实现此目标:

a = {'b': 1}
c = a.copy()
c.update({'b': 2})

print a # {'b': 1}
print c # {'b': 2}

请注意,这将只创建一个浅拷贝,所以如果字典包含可变对象——如另一个字典、列表或其他对象——那么所有拷贝将再次引用相同的底层对象(就像您的原始代码一样)。如果要避免这种情况,则可以创建字典的深拷贝
import copy
a = {'b': {'c': 1}}
b = copy.deepcopy(a)
b['b'].update({'c': 2})

print a # {'b': {'c': 1}}
print b # {'b': {'c': 2}}

我有一个类似于a={'b':'{"g": 4}'}的东西。在这种情况下,我能否只使用.copy()? - Rajeev
如前所述,如果您存储可变对象,例如另一个字典,则需要创建深层副本。 - poke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接