Python 3.x li=[0]*10和li=[set()]*10之间有什么区别

Python 3.x li=[0]*10和li=[set()]*10之间有什么区别,python-3.x,Python 3.x,用Python li = [0] * 3 li[0] = 1 # li == [1, 0, 0] 这个很好用 li = [set()] * 3 li[0].add(1) # li == [{1}, {1}, {1}] 这将为列表中的所有对象添加1。 这两者的区别是什么?这里: li = [0] * 3 li[0] = 1 创建一个包含三个元素的列表,所有元素都是不可变的数字0。然后用不可变的数字1替换第一个元素 鉴于: li = [set()] * 3 li[0].add(1) 创建一个

用Python

li = [0] * 3
li[0] = 1
# li == [1, 0, 0]
这个很好用

li = [set()] * 3
li[0].add(1)
# li == [{1}, {1}, {1}]
这将为列表中的所有对象添加1。 这两者的区别是什么?

这里:

li = [0] * 3
li[0] = 1
创建一个包含三个元素的列表,所有元素都是不可变的数字0。然后用不可变的数字1替换第一个元素

鉴于:

li = [set()] * 3
li[0].add(1)
创建一个集合(不是三个集合),并将其放入列表中三次。然后引用列表的第一个元素,当然是集合,并在其中添加一个数字。由于只创建了一个集合,这似乎会修改列表中的每个元素(因为它们都是相同的)


有关Python中
[x]*n
的危险的更多信息,请参阅:

Python中的对象通过引用存储和使用。当你写作时:

li = [set()] * 3

您正在创建一个对象,然后复制其引用;而不是对象本身。

首先,您将在该位置放置一个新对象。在第二种情况下,您正在修改对象。由于您只创建了一个对象,并且只将其放入列表中3次,因此看起来它修改了所有三个集合,但实际上它只是一个集合显示了三次。在第一种情况下,您创建了一个包含10个不可变对象(零)的列表,每个对象都是不同的对象。在第二种情况下,创建一个包含10个可变集合对象的列表,每个对象都是对同一集合的引用。在该位置用1替换新的、不可变的数字对象中的0。修改集合会影响列表中的所有集合,因为它们都指向同一个可变的集合对象。另外请看Btw@jpp,我不认为这个问题是“Python:list of list”的重复。这更具体地说是关于列表的列表,而当前的问题更一般地是关于不可变和可变对象类型的列表。相关的是的,但不同的足够值得它自己的空间。