字典赋值会导致Python中指向同一个对象吗?

2024-04-19 23:52:19 发布

您现在位置:Python中文网/ 问答频道 /正文

在用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

很明显,dictionary&list赋值不同于string赋值。但它是如何工作的呢?我在找一些解释或相关资源。有人能帮我吗?提前谢谢。你知道吗


Tags: 代码字典设计模式dictgoodprintthing赋值
2条回答
  1. Python知道名称和值。你知道吗
  2. 执行x = something时,xsomething值的新名称。你知道吗
  3. 分配从不复制数据。你知道吗

考虑到这一点,让我们看两个例子:

当你这么做的时候

dict2 = dict1

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

当你这么做的时候

str2 += " thing"

您正在将名称str2重新绑定到str2 + " thing"的结果。您正在构建一个全新的字符串,并重新绑定名称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]操作时,您将构建一个新列表并重新绑定名称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。使用+=时,字符串的行为与预期一致,即生成一个新字符串并重新分配名称。你知道吗

对标题中提出的问题的回答是“是”。但这并不是特定于dict和list的,对于任何对象都是完全相同的。你知道吗

赋值和赋值都不是真的。唯一的区别是dict和list允许您对它们进行变异;您可以看到您的代码在每种情况下都做了不同的事情-对dict执行列表和键赋值的append,但对字符串执行+=操作。这些是不同的操作,所以它们有不同的行为并不奇怪。你知道吗

相关问题 更多 >