【问题标题】:Python list of lists [duplicate]Python列表列表[重复]
【发布时间】:2012-10-21 10:20:59
【问题描述】:

可能重复:
Unexpected feature in a Python list of lists

我想在 Python 中创建一个列表列表,但显然这不起作用,因为更改一个数字会改变几个。为什么会这样,我该如何解决?

>>> a = [[0]*3]*4
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0], [1, 0, 0]]

【问题讨论】:

  • 不要使用*。它制作副本。改用列表推导
  • @MarkTolonen 是的,我已经投票结束这个问题。

标签: python list


【解决方案1】:

您发现的是classic Python pitfall

x = [0]*3 是一个列表。那里没问题,但是[x]*4 创建了一个列表,其中包含对完全相同的列表x 的4 个引用。因此,修改第一个元素 x 也会修改其他元素。

相反,如果你这样做:

In [193]: a = [[0]*3 for i in range(4)]

然后您会在列表中获得 4 个不同的项目:

In [194]: a[0][0] = 1

In [195]: a
Out[195]: [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

【讨论】:

  • StackOverflow 需要能够为答案添加书签。这是一个很好的例子。
  • @JonathanVanasco:为问题加注星标。
  • 我为这个问题加了星标。我想给答案加星标。
【解决方案2】:

在 Python 中,[x]*n 创建一个新列表,其中 n 引用 x。如果x 是不可变的(字符串、元组等),这是非常好的,但是如果x 是可变的,它会变得相当混乱,因为对一个元素的更改会影响x,因此似乎会影响所有元素列表。

所以,解决方案是使用列表推导来创建n 新事物:

[x for _ in xrange(n)] # we use _ here as a "dummy variable"

在你的情况下,它看起来像

a = [[0]*3 for _ in xrange(4)]

【讨论】:

    【解决方案3】:

    不要使用*。使用列表理解并创建如下:

    >>> a = [[0 for i in range(3)] for j in range(4)]
    >>> a[0][0] = 1
    >>> a
    [[1, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
    

    请参阅 unutbu 和 nneonneo 的答案以获得更好的解释。

    【讨论】:

    • 其实,如果* 复制就好了。正确的说法是它复制,只是额外的引用。
    • 嗯,我已阅读您的回答;好的。删除了声明。
    【解决方案4】:

    当在列表中使用* 时,它会创建副本,所以当您使用a[0][0]=1 时,所有其他子列表都会复制这个。

    要解决此问题,请使用 generator expression 创建您的列表。

    【讨论】:

    • 实际上,问题在于它复制,而不是它。
    猜你喜欢
    • 2023-04-09
    • 2015-04-25
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-26
    • 2015-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多