当我将一个字典分配给另一个变量时,为啥 Python 会同时更新两个字典? [复制]

Posted

技术标签:

【中文标题】当我将一个字典分配给另一个变量时,为啥 Python 会同时更新两个字典? [复制]【英文标题】:When I assign a dict to another variable, why does Python update both dicts? [duplicate]当我将一个字典分配给另一个变量时,为什么 Python 会同时更新两个字典? [复制] 【发布时间】:2014-03-26 02:11:28 【问题描述】:

使用字典时如何避免以下情况

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

【问题讨论】:

这里 'a' 和 'b' 指向同一个内存位置。因此 'a' 的变化反映在 'b' 中。 print(id(a),id(b)) 并看到两者具有相同的 id。 【参考方案1】:

通过使用字典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() 不,a['b'] 和 c['b'] 将引用同一个目录,使用 deepcopy()。【参考方案2】:

尝试:

c = a.copy()

还可以看到这个: Deep copy of a dict in python

它允许您在字典中按值列表复制

【讨论】:

【参考方案3】:

ac 两个变量都引用了同一个 dict 对象,因此当您通过变量 c 对其进行变异时,基础 dict 对象会发生变化。由于a 指向同一个对象,因此这些更改也将从那里可见。

如果您想让ac 都引用一个相互独立的字典,那么您需要复制该字典,这样您才能真正收到两个单独的对象。你可以使用dict.copy

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

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

请注意,这只会创建一个浅拷贝,因此如果字典包含可变对象(如另一个字典、列表或其他对象),那么所有副本将再次引用相同的底层对象(就像您的原始代码一样) .如果你想避免这种情况,你可以创建a deep copy of the dictionary:

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() 如前所述,如果您像存储另一个字典一样存储可变对象,则需要创建一个深拷贝。【参考方案4】:

显然您的问题已得到解答。但这里可能有帮助的是纠正你的心理模型。

在 Python 中,变量不存储值,它们命名值。查看this article 中指向酒店的雕像示例。

检查是否引用同一个对象的一种快速简便的方法是打印变量的 ID:

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

【讨论】:

以上是关于当我将一个字典分配给另一个变量时,为啥 Python 会同时更新两个字典? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥没有给另一个进程访问内存位置的权限?

当我将此数据帧转换为字典时,为啥索引设置不正确?

将一个枚举类型分配给另一个枚举类型

将绑定传递给类型属性包装器的变量 - 失去基础类型

将结构的第一个变量分配给另一个

为啥尽管我在变量中使用 malloc 分配更多内存,但当我打印变量的大小时,它仍然显示更少的内存/字节? [复制]