2

可能重复:
追加到子列表追加到每个子列表

二维列表初始化为grid=[[False]*N] *N

打印网格产生:

[[False, False, False, False], [False, False, False, False], [False, False, False, False], [False, False, False, False]]

现在我希望第 1 行和第 1 列中的元素为真。我只希望第 1 行和第 1 列中的元素为真。其他元素必须为假。

grid[0][0]=True

在我将 grid[0][0] 设置为 true 后,打印网格会产生:

[[True, False, False, False], [True, False, False, False], [True, False, False, False], [True, False, False, False]]

但是现在每一行的第一个元素都是真,但我只希望第一行的第一个元素是真。

请帮忙。我是 Python 新手。

4

2 回答 2

3

将单个引用数据类型相乘只会创建相同类型的多个引用。这意味着 [True]*N 实际上是元素 [True] 的相同实例的 N 倍

因此,改变一个会在不经意间改变另一个

正如您在以下示例中看到的,

>>> grid = [[True]]*10
>>> grid = [True]*10
>>> [id(e) for e in grid]
[505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788, 505379788]

它显示所有元素实际上都是同一个实例。

但是因为这里的元素不是可变类型,所以在这里更改不会成为问题,因为更改其中一个元素只会分配一个新实例。

可变类型发生问题

>>> [id(e) for e in grid]
[66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744]
>>> grid[0][0]=False
>>> [id(e) for e in grid]
[66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744, 66523744]
>>> grid
[[False], [False], [False], [False], [False], [False], [False], [False], [False], [False]]

要克服它,您需要了解哪些是可变类型并避免复制它,而是创建相同可变类型的新多个实例

所以这里作为一个列表是一个可变类型,你需要创建多个实例,可能通过列表理解

[[False]*N for _ in range(N)]
于 2013-01-07T06:00:14.957 回答
2

就像这个问题一样,您的列表实际上指向同一个列表。相反,将您的列表定义为:

[[False] * N for i in xrange(N)]

或者在 Python 3 中:

[[False] * N for i in range(N)]

然后修改一个元素将修改该元素。

请注意,Python 3range函数也适用于 Python 2 - 但是在 Python 2 中,该range函数返回一个列表,而不是rangePython 3 中的xrange对象和 Python 2 中的对象,它们都是迭代器。

于 2013-01-07T05:59:52.080 回答