在Python中向二维列表追加数据
在Python中向二维列表追加数据
我在Python中遇到了一个奇怪的行为,如果可能的话,我希望有人能解释一下。
我创建了一个空的二维列表:
listy = [[]]*3 print listy [[], [], []]
以下代码的运行结果符合我的预期:
listy[1] = [1,2]
得到 [[], [1,2], []]
listy[1].append(3)
得到 [[], [1,2,3], []]
然而,当我向其中一个空列表添加元素时,Python会将元素添加到所有子列表中,如下所示:
listy[2].append(1)
得到 [[1], [1,2,3], [1]]
。
有人能解释一下为什么会出现这种行为吗?
在Python中,使用[[]]*3
创建一个2D列表并不等同于使用[[], [], []]
。这是因为前者创建的是一个包含了3个相同实例的列表,而后者创建的是包含了3个不同实例的列表。
具体来说,当我们使用[[]]*3
创建一个2D列表时,实际上是创建了一个包含了3个相同实例的列表。换句话说,这三个列表引用都指向同一个列表实例。这意味着当我们对其中一个列表进行修改时,其他两个列表也会随之改变。
这种现象可能会导致一些意想不到的问题。例如,假设我们使用a = []
创建了一个空列表,并将其作为元素添加到另一个列表listy
中的三个位置上。这样,listy
实际上是包含了三个相同实例的列表。
为了解决这个问题,我们可以使用不同的实例来创建2D列表。一种常见的方法是使用列表推导式。例如,我们可以使用[[ ] for _ in range(3)]
来创建一个包含了3个不同实例的2D列表。
另一种解决方法是使用copy()
方法来创建列表的副本。这样,我们可以确保每个列表引用都指向不同的实例。例如,我们可以使用[[]]*3
创建一个2D列表,然后使用listy = [a.copy() for a in [[]]*3]
来创建一个包含了3个不同实例的listy
列表。
总结起来,当我们需要创建一个包含多个列表的2D列表时,应该注意使用不同的实例来避免出现意想不到的问题。我们可以使用列表推导式或者copy()
方法来创建不同实例的列表。
问题的原因是在创建列表时,没有创建三个独立的空列表,而是创建了一个空列表,然后创建了一个新列表,其中包含对同一个空列表的三个引用。解决方法是使用以下代码:
listy = [[] for i in range(3)]
运行示例代码后,会得到预期的结果:
>>> listy = [[] for i in range(3)] >>> listy[1] = [1,2] >>> listy [[], [1, 2], []] >>> listy[1].append(3) >>> listy [[], [1, 2, 3], []] >>> listy[2].append(1) >>> listy [[], [1, 2, 3], [1]]
这样做非常合理。谢谢。
这是我在Python中遇到的最奇怪的功能,几乎像一个bug一样。