我想在python中理解这里的小片段:
>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
>>> y[0]
'foo'
>>> y[0] = "fooooooo"
>>> y[1]
[1, 2, 3]
>>> y[1][0]=4
>>> print x
['foo', [4, 2, 3], 10.4]
>>> print y
['fooooooo', [4, 2, 3], 10.4]
>>> z = ['foo', [1,2,3], 10.4]
>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
>>> y[0] = "fooooooo"
>>> y[1]
[1, 2, 3]
>>> y[1][0]=4
>>> print x
['foo', [4, 2, 3], 10.4]
>>> print y
['fooooooo', [4, 2, 3], 10.4]
>>> print z
['foo', [1, 2, 3], 10.4]
>>> y = list(z)
>>> y[1][0]=6
>>> print y
['foo', [6, 2, 3], 10.4]
>>> y = list(z)
>>> print z
['foo', [6, 2, 3], 10.4]
>>> print x
['foo', [4, 2, 3], 10.4]
这是如何运作的。 如果改变y的列表元素,它会反映到x。它可能是python的基础,但我仍然没有抓住这个
答案 0 :(得分:4)
y = list(x)
上述语句创建列表x
的浅表副本。
浅复制构造一个新的复合对象,然后(尽可能)将对它的引用插入到原始对象中找到的对象。
在这里,您确实获得了一个新对象y
,但由于其中的列表是一个可变对象,因此您将获得对原始对象的引用。而且,如果您继续创建这些浅拷贝,列表对象将在所有副本之间共享。
您可以使用id
:
>>> id(x)
140183460314288
>>> id(y)
140183460372992 # this is different from y
>>> id(x[1])
140183460314864
>>> id(y[1]) # this is same as x[1]
140183460314864
>>> y1 = list(y) # another shallow copy from y
>>> id(y1[1])
140183460314864 # this is still same
如果您希望某个行为需要修改y
的内容而不影响x
,则需要执行deepcopy
:
>>> >>> from copy import deepcopy
>>> z = deepcopy(x)
>>> id(z[1])
140183460405400 # this is different now because of deepcopy
您可以看到此ID与id(x[1])
不同,现在如果您尝试修改内容,则不会反映在x
中。
答案 1 :(得分:3)
我猜你唯一感到困惑的是,设置一个变量的嵌套列表的元素将改变所有其他变量的嵌套列表。原因很简单:Python在每个变量中使用相同的嵌套列表(例如,完全相同的内存)。当您说y = list(x)
时,Python会将x
的所有原子元素复制到y
中,但只复制对嵌套列表的引用。由于在任何地方都使用相同的嵌套列表,因此将其修改为一个地方会在任何地方修改它。
通过玩l1 = [0]*3
和l2 = [[0]]*3
,您还可以看到类似的行为; l1
和l2
的行为方式之间的差异是您正在观察的行为的另一个例子。
答案 2 :(得分:1)
>>> x = ['foo', [1,2,3], 10.4]
>>> y = list(x)
y
是x
的副本。 y[1]
在x
的{{1}}列表中包含参考的副本。因此[1,2,3]
和y[1]
是对同一列表的2个引用。