python - 字典赋值是否导致指向 Python 中的同一个对象?

标签 python dictionary

在用 Python 实现一些设计模式时,我发现字典中有一些有趣的东西看起来很不寻常。我用 dict 构造函数创建了一个变量 dict1 。然后将dict1赋值给dict2。但是,当更改 dict2 中的某个键的值时,它会影响 dict1

代码:

dict1 = dict(a=1, b=2)
dict2 = dict1
print("dict1 = ", dict1)
print("dict2 = ", dict2)

# assigning value of key 'a' in dict2 only
dict2['a'] = 0
print("---------------------------")
print("dict1 = ", dict1)
print("dict2 = ", dict2)

输出:

dict1 =  {'b': 2, 'a': 1}
dict2 =  {'b': 2, 'a': 1}
---------------------------
dict1 =  {'b': 2, 'a': 0}
dict2 =  {'b': 2, 'a': 0}

我也发现了列表的相同类型的行为:

list1 = [1, 2, 3]
list2 = list1
print(list1, list2)
print("---------------------------")
list2.append(4)
print(list1, list2)

输出:

[1, 2, 3] [1, 2, 3]
---------------------------
[1, 2, 3, 4] [1, 2, 3, 4]

但不是在字符串中:

str1 = "Good"
str2 = str1
print(str1, ",", str2)
print("---------------------------")
str2+=" thing"
print(str1, ",", str2)

输出:

Good , Good
---------------------------
Good , Good thing

很明显,字典和列表赋值不同于字符串赋值。但是它是如何工作的呢?我正在寻找一些解释或相关资源。谁能帮我吗 ?提前致谢。

最佳答案

  1. Python 知道名称和值。
  2. 当您执行 x = something 时,xsomething 值的新名称。
  3. 赋值从不复制数据。

考虑到这一点,让我们回顾一下这两个例子:

当你做的时候

dict2 = dict1

dict2 是字典 {'a':1, 'b':2} 的新名称 它也有名称 dict1 。字典的所有更改都将在所有名称中可见!

当你做的时候

str2 += " thing"

您正在重新绑定(bind)名称str2str2 + "thing" 的结果。您正在构建一个全新的字符串,并重新绑定(bind)名称 str2str1str2 现在是不同字符串的名称,str1 仍指向原始字符串。

要记住的最后一件事/陷阱:有时,+= 运算符会欺骗您,x += y 会做一些不同于 x 的事情= x + y.

这是一个例子:

>>> x = [1, 2, 3]
>>> y = x
>>> x = x + [4, 5, 6]
>>> x
[1, 2, 3, 4, 5, 6]
>>> y
[1, 2, 3]

正如预期的那样,当您执行 x = x + [4, 5, 6] 时,您构建了一个新列表并重新绑定(bind)名称 xy 仍然指向旧列表。然而……

>>> x = [1, 2, 3]
>>> y = x
>>> x += [4, 5, 6]
>>> x
[1, 2, 3, 4, 5, 6]
>>> y
[1, 2, 3, 4, 5, 6]

这是出乎意料的,因为从概念上讲

x += [4, 5, 6] 

应该和

一样
x = x + [4, 5, 6]

发生的事情是,当你使用 += 时,你正在调用 x 上的 __iadd__,即发生的事情是 x.__iadd__ ([4, 5, 6])

在列表的情况下,__iadd__ 扩展列表而不是构建新的列表对象,所以 x += [4, 5, 6 ] 相当于

x.extend([4, 5, 6]) 

然后返回x。使用 += 时字符串的行为符合预期,即构建一个新字符串并重新分配名称。

关于python - 字典赋值是否导致指向 Python 中的同一个对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35676300/

相关文章:

python - 给定一个 "jumbled"列表 L,得到一个列表,其中每个元素都是 L 对应元素的索引,如果 L 已排序

python - 有没有办法使用 Jinja2/Ansible 设置整数的默认最小值?

python - 如何在Python中绘制直方图?

python - Flask 单元测试抛出错误 : has no attribute 'csrf_token' in Jinja2 template

javascript - 从数组的字典 JS 获取数据时出现问题

Python 访问字典列表中的值

每个实例的 Python LRU 缓存装饰器

python - 如何将列表元素添加到字典中

具有相同键类型和不同项目类型的c++映射

python-2.7 - PYTHON 2.7 - 修改列表列表并重新组装而不改变