Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当我复制并编辑此列表时,到底发生了什么?_Python_List_Python 3.x - Fatal编程技术网

Python 当我复制并编辑此列表时,到底发生了什么?

Python 当我复制并编辑此列表时,到底发生了什么?,python,list,python-3.x,Python,List,Python 3.x,我根本不明白为什么会发生这种情况: A = [[1,0], [2,2]] B = list(A) print('start A:', A, 'start B:', B) A[0][0] = 999 print('end A:', A, 'end B:', B) 这将返回: start A: [[1, 0], [2, 2]] start B: [[1, 0], [2, 2]] end A: [[999, 0], [2, 2]] end B: [[999, 0], [2, 2]] 列表A和B最

我根本不明白为什么会发生这种情况:

A = [[1,0], [2,2]]
B = list(A)

print('start A:', A, 'start B:', B)
A[0][0] = 999
print('end A:', A, 'end B:', B)
这将返回:

start A: [[1, 0], [2, 2]] start B: [[1, 0], [2, 2]]
end A: [[999, 0], [2, 2]] end B: [[999, 0], [2, 2]]
列表A和B最终是相同的,即使我显式地从A复制了B。这只发生在我执行类似于A[0][0]=999的操作时;如果我用A[0]=999替换它,那么最后A和B是不同的


这背后的原因是什么?有没有办法以这种方式改变A而不影响B

A和B都包含相同的两个列表

您的代码大致相当于:

x = [1, 0]
y = [2, 2]

A = [x, y]
B = [x, y]

操作
A[0][0]=999
实际上只是执行
x[0]=999
。也就是说,它不修改A本身,而是修改列表的第一个元素
x
。因为A和B都引用了
x
,所以两者都会看到变化。

像您这样简单的复制操作是浅层的,它只复制一层深的项,不会递归到嵌套结构中。你需要

>>> import copy
>>> A = [[1,0], [2,2]]
>>> B = copy.deepcopy(A)
>>> print('start A:', A, 'start B:', B)
start A: [[1, 0], [2, 2]] start B: [[1, 0], [2, 2]]
>>> A[0][0] = 999
>>> print('end A:', A, 'end B:', B)
end A: [[999, 0], [2, 2]] end B: [[1, 0], [2, 2]]
您正在创建原始列表的浅表副本,即新列表,其中包含对与原始列表相同的对象的新引用

修改新列表对象不会更改原始列表。修改新列表中的对象不会修改旧列表中的对象,因为它们是相同的

要获得完全独立的列表,请使用创建深度副本。

a
B
是计算机中相同内存块的两个不同名称

A
B
是两个独立的列表对象,但是
A[0]
B[0]
是计算机中相同内存块的两个不同名称。从解释器中尝试以下操作:

id(B)
id(A)
id(B[0])
id(A[0])
Python代码操纵对对象的引用

分配给变量只是绑定一个名称以引用一个对象

列表由一组对对象的引用组成<代码>列表(A)查找
A
中引用的所有对象,并创建一个包含所有相同对象引用的新列表。因此,如果
A
是一个列表列表,
list(A)
创建一个新列表,其中引用了
A
中的相同列表。因此,在
A
和新列表中都可以看到更改任何子列表

copy.deepcopy
的存在是为了在您需要某个内容的完整“深度”拷贝时帮助您解决此问题


一旦您学会将Python代码视为操纵对此类对象的引用,您将直观地了解代码何时可能最终从多个位置引用同一对象,尽管可能总会有一些模糊的情况让您感到惊讶。

不,它们不是。它们是单独的列表对象。