有谁能请解释这里发生的事情?我理解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
>>>
答案 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)
这可能有所帮助(只需在每一行转储list
和a
的值):
#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
>>>