更改一个列表中的元素会更改多个列表[重复]

Posted

技术标签:

【中文标题】更改一个列表中的元素会更改多个列表[重复]【英文标题】:Changing an element in one list changes multiple lists [duplicate] 【发布时间】:2013-09-27 14:38:41 【问题描述】:

我有一个列表说mysolution

>>>mySolution
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> mySolution[0][0] = 1    
>>> mySolution
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]

预期输出:

[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

为什么我的列表中的所有第一个元素都被更改为 1? 我只想将第一个列表的第一个元素更改为 1。

【问题讨论】:

哦,那个讨厌的n * list操作员!老实说,我不介意在检测到可变类型时抛出异常.. 【参考方案1】:

重要的是您如何创建原始mysolution 列表。看起来,它包含四次相同的列表,这就是为什么更改一次会使其在所有四个位置都发生更改的原因。

要像这样初始化独立的零填充列表,您可以执行以下操作:

mysolution = [[0] * 4 for i in range(4)]

【讨论】:

mySolution=[0]*4 mySolution = [mySolution]*4 @Pavan:这行不通,因为它是同一个列表四次。 poke 的解决方案避免了这种情况。【参考方案2】:

很可能您是这样创建列表的:

mySolution = [0]*4
mySolution = [mySolution]*4

或等价:

mySolution = [[0]*4]*4

上述任何一个 sn-ps 都会创建一个包含四个子列表的列表,这些子列表是 完全相同的子列表的副本,因此对一个子列表的任何修改都将反映在其他子列表上 - 它们是一个和相同的。解决方案是创建四个不同的子列表:

mySolution = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

或者更短一点:

mySolution = [[0]*4 for _ in xrange(4)]

【讨论】:

【参考方案3】:

因为所有包含的列表实际上是同一个列表。当你这样做时:

l = [0, 0, 0, 0]
my_solution = [l, l, l]

那么,my_solution[0]my_solution[1]my_solution[2] 是对同一对象 (l) 的引用。

如果您在一个位置修改列表,它会随处更改。那是因为列表是可变的对象。

改为使用多个列表:

l1 = [0, 0, 0, 0]
l2 = [0, 0, 0, 0]
l3 = [0, 0, 0, 0]
my_solution = [l1, l2, l3]

这将按预期工作。

【讨论】:

【参考方案4】:

请注意,这很好:

mySolution = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
mySolution[0][0] = 1    
print mySolution

>>> 
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

这完全取决于您如何初始化solution。这个

mySolution = [[0, 0, 0, 0]]*4
mySolution[0][0] = 1    
print mySolution

给予

>>> 
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
>>> 

因为这里mySolution 中的每个数组[0, 0, 0, 0] 都是[[0, 0, 0, 0]]*4 中的初始化数组[0, 0, 0, 0] 的副本。如果您更改第一个数组的第一个元素,它的副本也会更改。

使用此初始化mySolution = [[0, 0, 0, 0] for x in range(4)],您不会复制数组,而是将[0,0,0,0] 附加四次,得到您期望的结果。

【讨论】:

以上是关于更改一个列表中的元素会更改多个列表[重复]的主要内容,如果未能解决你的问题,请参考以下文章

修改源项目会更改列表项目吗? [重复]

Python中的递归函数不会更改列表[重复]

使用相同的变量附加python列表会导致在所有列表位置注册变量的新更改[重复]

使用 jQuery 更改浏览器地址栏 URL [重复]

在下拉列表中的页面加载上已经选择了一个选项,并且还可以更改 [重复]

Python中的函数更改列表值而不是变量值[重复]