官方文档上给出的一个小例子,来看一下效果
lists = [[]] * 3
lists #[[], [], []]
lists[0].append(3)
lists #[[3], [3], [3]]
What has happened is that [[]] is a one-element list containing an empty list, so all three elements of [[]]*3are references to this single empty list. Modifying any of the elements of lists modifies this single list.you can create a list like that:
原因在于[[]] 是一个只包含一个空列表的列表,[[]]*3操作使得复制产生的列表中,包含了三个指向同一个空列表对象,修改其中任一个列表元素都会对,其他的列表内容也会跟着变化,我们可以像下面这样创建list:
lists1 = [[] for i in range(3)]
lists1 #[[], [], []]
lists1[0].append(2)
lists1 #[[2], [], []]
举个详细的例子
1.第一种形式
row=['_'] * 3
board = []
for i in range(3):
board.append(row)
2.第二种形式
board = []
for i in range(3):
row=['_'] * 3
board.append(row)
3.第三种形式
weird_board = [['_'] * 3] * 3
4.第四种形式
board = [['_'] * 3 for i in range(3)]
首先,说一下,这几种形式的区别,然后确定最终最优的选择
第一,第一种方法和三种方法效果是一样的,同样,第二种方法和第四种方法效果是一样的,那么,第一种和第三种方法有什么问题呢,就是说,在迭代过程中,它其实是把同一个列表对象引用,放在了同一张列表中三次,当你修改内部的列表中某一元素时,效果就会出现。所以,在具体的使用中,建议使用第四种方法,这也正是列表推导式常用的地方,即用于产生新的列表。