列表清单:为什么在[1] [0]处更改值也会改变[0] [0]?

时间:2013-03-25 22:27:01

标签: python list

有谁能请解释这里发生的事情?我理解python int是按值分配的(而不是引用)。

>>> alist = [1,2,3]
>>> a = [[0]*3]*4
>>> a[0][0] = len(alist)
>>> alist.append(1)
>>> a[1][0] = len(alist)
>>> a[0][0]a
4
>>> 

4 个答案:

答案 0 :(得分:4)

使用*表示法创建列表时,您将重复相同的元素。不是复制元素,而是完全相同的对象。

当您重复的对象是不可变的,例如整数时,您将不会注意到。

当对象是可变的(例如列表)时,您会重复相同的列表。如果您对一个列表进行了更改,那么您将对所有列表进行更改。

在您的情况下,您对元素[1]进行了更改,并将其反映在元素[0]中。

答案 1 :(得分:3)

问题是您的外部列表包含相同内部列表值的多个副本。以下是您的说法:

a = [[0]*3]*4
print(a[0] is a[1]) # prints True

如果你想要一个零的二维列表,我建议对外部部分使用列表推导,以便你得到单独的内部列表实例:

a = [[0]*3 for _ in range(4)]
print(a[0] is a[1]) # prints False

a[0][0]=1
print(a[1][0]) # prints 0

答案 2 :(得分:2)

这可能有所帮助(只需在每一行转储lista的值):

#With some commentary
>>> alist = [1,2,3] #Created a list with 3 elements
>>> alist
[1, 2, 3]
>>> a = [[0]*3]*4 #Created a list with 3 copies of one element and then copied it 4 times
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = len(alist) #Set the 0th element of the 0th copy to 3
>>> a #Now you can see where that value was copied
[[3, 0, 0], [3, 0, 0], [3, 0, 0], [3, 0, 0]]
#The rest is just a permutation of that first 'bug'
>>> alist.append(1)
>>> alist
[1, 2, 3, 1]
>>> a[1][0] = len(alist)
>>> a
[[4, 0, 0], [4, 0, 0], [4, 0, 0], [4, 0, 0]]
>>> a[0][0]
4

关于此代码的一个不直观的事情可能是[0]*3似乎做了你期望的事情而[[0]*3]*4没有。为此,我只能猜测(不是Python大师)单个长度的int列表是以一种看似直观的方式处理的,而列表列表又回归到复制方法。

答案 3 :(得分:0)

没问题。 [[0]*3]*4创建了一个列表,其中包含4个3个元素列表的副本。 a [0],a [1],a [2]和[3]都指向同一个列表。

>>> a=[[0]*3]*4
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0]='hello'
>>> a
[['hello', 0, 0], ['hello', 0, 0], ['hello', 0, 0], ['hello', 0, 0]]
>>> for mylist in a:
    ...     print id(a)
    ...
    42701168
    42701168
    42701168
    42701168
>>>