【问题标题】:2D list has weird behavor when trying to modify a single value [duplicate]尝试修改单个值时,二维列表有奇怪的行为[重复]
【发布时间】:2011-02-13 22:28:43
【问题描述】:

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

所以我对 Python 比较陌生,并且在使用 2D 列表时遇到了麻烦。

这是我的代码:

data = [[None]*5]*5
data[0][0] = 'Cell A1'
print data

这是输出(为便于阅读而格式化):

[['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None],
 ['Cell A1', None, None, None, None]]

为什么每一行都被赋值?

【问题讨论】:

  • 天哪,我以前是不是被同样的问题困住了.. :)

标签: python python-2.7 list 2d


【解决方案1】:

正如包含列表的python library reference for sequence types 所说

还要注意副本很浅;嵌套结构不会被复制。这常常困扰着新的 Python 程序员。考虑:

>>> lists = [[]] * 3
>>> lists
  [[], [], []]
>>> lists[0].append(3)
>>> lists
  [[3], [3], [3]]

发生的事情是 [[]] 是一个包含一个空列表的单元素列表,因此 [[]] * 3 的所有三个元素都是(指向)这个单个空列表的。修改列表的任何元素都会修改这个单个列表。

您可以通过这种方式创建不同列表的列表:

>>> lists = [[] for i in range(3)]  
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
  [[3], [5], [7]]

【讨论】:

    【解决方案2】:

    在 python 中,每个变量都是一个对象,因此也是一个引用。您首先创建了一个包含 5 个 None 的数组,然后您构建了一个包含 5 次相同对象的数组。

    【讨论】:

      【解决方案3】:

      这会生成一个列表,其中包含五个对相同列表的引用:

      data = [[None]*5]*5
      

      使用类似这样的东西来创建五个单独的列表:

      >>> data = [[None]*5 for _ in range(5)]
      

      现在它可以满足您的期望:

      >>> data[0][0] = 'Cell A1'
      >>> print data
      [['Cell A1', None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None],
       [None, None, None, None, None]]
      

      【讨论】:

        猜你喜欢
        • 2021-11-25
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-04
        • 1970-01-01
        • 2016-01-28
        相关资源
        最近更新 更多