代码之家  ›  专栏  ›  技术社区  ›  Brian

当试图修改单个值时,2d列表有奇怪的行为[重复]

  •  46
  • Brian  · 技术社区  · 15 年前

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

    所以我对python比较陌生,我在处理二维列表时遇到了困难。

    这是我的代码:

    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]]
    

    为什么每一行都被赋值?

    3 回复  |  直到 7 年前
        1
  •  64
  •   Mark Byers    15 年前

    这是一个列表,其中有五个引用 相同的 名单:

    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]]
    
        2
  •  14
  •   mmmmmm    8 年前

    作为 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]]
    
        3
  •  2
  •   lfagundes    15 年前

    在Python中,每个变量都是一个对象,因此是一个引用。首先创建一个由5个nones组成的数组,然后用同一对象的5倍构建一个数组。