在用 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
很明显,字典和列表赋值不同于字符串赋值。但是它是如何工作的呢?我正在寻找一些解释或相关资源。谁能帮我吗 ?提前致谢。
最佳答案
- Python 知道名称和值。
- 当您执行
x = something
时,x
是something
值的新名称。 - 赋值从不复制数据。
考虑到这一点,让我们回顾一下这两个例子:
当你做的时候
dict2 = dict1
dict2
是字典 {'a':1, 'b':2}
的新名称 它也有名称 dict1
。字典的所有更改都将在所有名称中可见!
当你做的时候
str2 += " thing"
您正在重新绑定(bind)名称str2
到str2 + "thing"
的结果。您正在构建一个全新的字符串,并重新绑定(bind)名称 str2
。 str1
和 str2
现在是不同字符串的名称,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)名称 x
。 y
仍然指向旧列表。然而……
>>> 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/