我创建了一个列表的列表:
>>> xs = [[1] * 4] * 3
>>> print(xs)
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
然后,我改变了最里面的一个值:
>>> xs[0][0] = 5
>>> print(xs)
[[5, 1, 1, 1], [5, 1, 1, 1], [5, 1, 1, 1]]
为什么每个子列表的第一个元素都变成了5?
参见:
我如何克隆一个列表,使它不会在分配后意外改变?寻找解决问题的方法
Python:对于字典列表的类似问题,字典列表只存储每次迭代中最后追加的值
如何初始化一个字典,其值是不同的空列表?对于列表字典的类似问题
通过使用内置的列表函数,您可以这样做
a
out:[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#Displaying the list
a.remove(a[0])
out:[[1, 1, 1, 1], [1, 1, 1, 1]]
# Removed the first element of the list in which you want altered number
a.append([5,1,1,1])
out:[[1, 1, 1, 1], [1, 1, 1, 1], [5, 1, 1, 1]]
# append the element in the list but the appended element as you can see is appended in last but you want that in starting
a.reverse()
out:[[5, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
#So at last reverse the whole list to get the desired list
@spelchekr from Python list乘法:[[…]*3制作了3个列表,这些列表在修改时相互镜像,我有同样的问题
“为什么只有外层的*3会产生更多的参考,而内部的则不会?”为什么不都是1s?”
li = [0] * 3
print([id(v) for v in li]) # [140724141863728, 140724141863728, 140724141863728]
li[0] = 1
print([id(v) for v in li]) # [140724141863760, 140724141863728, 140724141863728]
print(id(0)) # 140724141863728
print(id(1)) # 140724141863760
print(li) # [1, 0, 0]
ma = [[0]*3] * 3 # mainly discuss inner & outer *3 here
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
ma[0][0] = 1
print([id(li) for li in ma]) # [1987013355080, 1987013355080, 1987013355080]
print(ma) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
下面是我在尝试上面的代码后的解释:
内部的*3也创建引用,但它的引用是不可变的,就像[&0,&0,&0],那么当你改变li[0]时,你不能改变const int 0的任何底层引用,所以你可以只改变引用地址为新的&1;
而ma = [&li, &li, &li]且li是可变的,因此当你调用ma[0][0] = 1时,ma[0][0]等于&li[0],因此所有的&li实例将其第一个地址更改为&1。
我正在补充我的答案,以图解方式解释同样的问题。
你创建2D的方式,创建一个浅列表
arr = [[0]*cols]*row
相反,如果您希望更新列表中的元素,则应该使用
rows, cols = (5, 5)
arr = [[0 for i in range(cols)] for j in range(rows)]
解释:
可以使用以下命令创建列表:
arr = [0]*N
or
arr = [0 for i in range(N)]
在第一种情况下,数组的所有下标都指向同一个整数对象
当你给一个特定的索引赋值时,就会创建一个新的int对象,例如arr[4] = 5
现在让我们看看当我们创建一个list of list时会发生什么,在这种情况下,top list的所有元素都指向同一个列表
如果你更新任何索引的值,就会创建一个新的int对象。但是由于所有顶级列表索引都指向同一个列表,所以所有行看起来都是一样的。您会觉得更新一个元素就是更新该列中的所有元素。
感谢Pranav Devarakonda提供的简单解释