【问题标题】:Python : how to append new elements in a list of list?Python:如何在列表列表中追加新元素?
【发布时间】:2012-06-27 05:29:41
【问题描述】:

这是一个非常简单的程序:

 a = [[]]*3

 print str(a)

 a[0].append(1)
 a[1].append(2)
 a[2].append(3)

 print str(a[0])
 print str(a[1])
 print str(a[2])

这是我期待的输出:

 [[], [], []]
 [1]
 [2]
 [3]

但是我得到了这个:

 [[], [], []]
 [1, 2, 3]
 [1, 2, 3]
 [1, 2, 3]

这里确实有一些我没有得到的东西!

【问题讨论】:

  • 您应该使用 lists 的列表,而不是标题推断的(相同)列表的列表。

标签: python list


【解决方案1】:

你必须这样做

a = [[] for i in xrange(3)]

不是

a = [[]]*3

现在可以了:

$ cat /tmp/3.py
a = [[] for i in xrange(3)]

print str(a)

a[0].append(1)
a[1].append(2)
a[2].append(3)

print str(a[0])
print str(a[1])
print str(a[2])

$ python /tmp/3.py
[[], [], []]
[1]
[2]
[3]

当您执行a = [[]]*3 之类的操作时,您会在一个列表中获得相同的列表[] 三次。 相同意味着当你改变其中一个时,你就改变了所有的(因为只有一个列表被引用了 3 次)。

您需要创建三个独立的列表来规避这个问题。你可以通过列表理解来做到这一点。您在这里构造一个由独立的空列表[] 组成的列表。在xrange(3) 上的每次迭代都会创建一个新的空列表(rangexrange 之间的区别在这种情况下并不那么重要;但是xrange 稍微好一点,因为它不会生成完整的列表数字,只是返回一个迭代器对象)。

【讨论】:

  • 如果有解释和使用xrange会更好
  • @okm 除非它是 python 3x :)
【解决方案2】:

您的方法的根本问题是,当您将列表乘以三时,结果列表包含三个相同列表。所以a[0]a[1]a[2] 都引用了同一个东西。当您附加到其中任何一个时,您将附加到同一个列表。这就是为什么您的append() 调用的效果似乎是三重的原因。

相反,在不引用相同列表的情况下生成列表列表。例如,您可以像这样使用列表推导式。

[[] for i in range(3)]

【讨论】:

    【解决方案3】:

    当你写作时:

    a = [[]]*3
    

    您不会复制内部空列表的 3 个副本,而是对同一对象进行 3 次引用。

    同样的方法,如果你这样做:

    b = [1,2,3]
    c = b
    c.append(4)
    print b
    

    你得到输出:

    [1, 2, 3, 4]
    

    那是因为 b 和 c 是同一个列表的两个不同的引用(你可能会说两个不同的名字)。您可以从任何引用更改对象,但您会看到所有引用的结果,因为它们指向同一事物。

    【讨论】:

      【解决方案4】:

      这会给你一个清晰的想法,在 l 所有对象都具有相同的 id() 并且都是可变的,因此编辑其中任何一个也会自动编辑另一个,因为它们都只是引用具有 id= 的同一个对象18671936和m都有不同的id(),所以都是不同的对象。

      >>> l = [[]]*4
      >>> for x in l:
              print(id(x))
      
      18671936 
      18671936
      18671936
      18671936
      
      >>> m=[[],[],[],[]]
      >>> for x in m:
              print(id(x))
      
      10022256
      18671256
      18672496
      18631696
      

      所以,你应该像这样创建你的列表:

      >>> a=[[] for _ in range(4)]
      >>> a[0].append(1)
      >>> a[2].append(5)
      >>> a
      [[1], [], [5], []]
      

      【讨论】:

        【解决方案5】:

        这里确实有一些我没有得到的东西!

        a = [[]]*3 这里的问题是您将列表设置为相同的引用,因为数组和字典都存储为引用。

        >>> a = [[]]*3
        >>> a[0] is a[1] or a[0] is a[2]
        True
        >>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2]
        True
        >>> 
        

        如果你执行 a = [{}]*3` 也会发生同样的事情

        因此,您必须小心,您可以执行列表理解 [[] for _ in xrange(3)] 或静态定义所有 3 个数组 [[], [], []]

        >>> a = [[] for _ in xrange(3)]
        >>> a[0] is a[1] or a[0] is a[2] or a[1] is a[2]
        False
        >>> 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-14
          • 2017-07-17
          • 2014-05-09
          • 1970-01-01
          • 1970-01-01
          • 2012-08-30
          相关资源
          最近更新 更多