【问题标题】:Modify element [0][0] in a Python 2D list [duplicate]修改 Python 2D 列表中的元素 [0][0] [重复]
【发布时间】:2012-12-20 20:53:19
【问题描述】:

可能重复:
append to a sublist appends to every sublist

二维列表初始化为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 新手。

【问题讨论】:

  • 正确格式化您的代码
  • @Abhijit:这本身就是 1000 个早期 SO 问题的副本。我想知道关于 SO 的 Python 问题中有多少百分比是一遍又一遍地重复相同的 10 个基本问题?
  • @abarnert:我相信我们应该将这 1000 个较早的 SO 问题之一放在 Python 常见问题解答中
  • @Abhijit:我猜。但它已经在官方 Python 教程和参考文档中,而且我认为我从未见过解释您可以在 list 上使用 * 而无需立即解释浅拷贝陷阱的教程,所以......你认为它会有很多好处吗?

标签: python


【解决方案1】:

乘以单个引用数据类型只会创建相同类型的多个引用。 意思是[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)]

【讨论】:

    【解决方案2】:

    很像this question,您的列表实际上指向同一个列表。相反,将您的列表定义为:

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

    或者在 Python 3 中:

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

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

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

    【讨论】:

    • 你可以做[False]*N - 这个“问题”只发生在可变对象上。
    • @Tim 当然,我怎么会忘记呢?编辑以反映这一点。
    • Note the Python 3 version is also backwards compatible, and works in Python 2.,不知道你为什么在这个问题上提到这个,但这并不完全正确
    • @Abhijit range 函数存在于 Python 2 中...它只是返回一个列表而不是 xrange 对象
    • @Volatility:范围为真,但一般意义上的陈述是不正确的。您可以突出显示您指的是 rangexrange 以及它在 Python 2 与 Python 3 中的用法差异
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2018-06-20
    • 2023-04-08
    • 2015-12-04
    • 2016-10-26
    • 1970-01-01
    相关资源
    最近更新 更多