4

我知道,当您对字典进行浅拷贝时,实际上是在复制参考资料。所以如果我这样做:

x={'key':['a','b','c']}
y=x.copy()

所以列表 ['a','b','c'] 的引用被复制到 y 中。每当我更改列表(x['key'].remove('a')例如)时, dict x 和 y 都会更改。这部分我明白了。但是当我考虑下面这样的情况时:

x={'user':'admin','key':['a','b','c']}
y=x.copy()

当我这样做时y['user']='guest', x['user'] 不会改变,但列表仍然共享相同的引用。所以我的问题是是什么使字符串与列表不同?这背后的机制是什么?

4

2 回答 2

14

你在做两件不同的事情。当你这样做

x['key'].remove('a')

你改变了引用的对象x['key']。如果另一个变量引用同一个对象,你也会从那个角度看到变化:

Pythontutor 可视化 Pythontutor可视化2

但是,在第二种情况下,情况就不同了:

PT 可见 3

如果你这样做

y['user']='guest'

重新绑定 y['user']到一个新对象。这当然不会影响x['user']或它引用的对象。

顺便说一句,这与可变对象与不可变对象无关。如果你做了

x['key'] = [1,2,3]

你也不会改变y['key']

PT 可见 4

在PythonTutor.com上以交互方式查看它。

于 2013-07-25T18:16:22.267 回答
5

不同之处在于,在一种情况下,您正在为字典键分配一个新值,而在另一种情况下,您正在修改现有值。注意两段代码的区别:

x['key'].remove('a')

这里没有任何=迹象。您没有在字典中分配任何内容。事实上,字典甚至几乎不“知道”发生了什么。你只是伸手去操作字典里面的一个对象。

y['user'] = 'guest'

在这里,您实际上是为字典键分配了一个新值。

你不能remove在第二种情况下做等效的事情,因为字符串是不可变的。但是,区别不是“因为字符串是不可变的”。不同之处在于您正在改变列表而不是字符串。您可以通过执行来获得第一种情况下第二个示例的行为

x['key'] = ['new', 'list']

这将为 中的键分配一个新值xy不受影响。

于 2013-07-25T18:19:09.050 回答