【问题标题】:Python list multiplication: [[...]]*3 makes 3 lists which mirror each other when modified [duplicate]Python 列表乘法:[[...]]*3 生成 3 个列表,修改时相互镜像 [重复]
【发布时间】:2011-10-05 00:25:45
【问题描述】:

为什么会这样?我真的不明白:

>>> P = [ [()]*3 ]*3
>>> P
[[(), (), ()], [(), (), ()], [(), (), ()]]
>>> P[0][0]=1
>>> P
[[1, (), ()], [1, (), ()], [1, (), ()]]

【问题讨论】:

  • 为什么只有外部*3 创建更多引用而内部没有?为什么不都是1s?

标签: python list multiplication


【解决方案1】:

您已经对同一个列表进行了 3 次引用。

>>> a = b = []
>>> a.append(42)
>>> b
[42]

你想这样做:

P = [[()] * 3 for x in range(3)]

【讨论】:

    【解决方案2】:

    列表是可变的,将列表乘以数字不会复制其元素。您可以尝试将其更改为列表推导式,因此它将评估 [()]*3 三次,创建三个不同的列表:

    P = [ [()]*3 for i in range(3) ]
    

    【讨论】:

    • 这个答案需要多加注意——“列表是可变的,列表乘以一个数字不会复制它的元素。”
    【解决方案3】:

    也可以这样写,好处是可以显示结构[[()]*3]*3

    >>> P=[i[:] for i in [[()]*3]*3]
    >>> P[0][0]=1
    >>> P
    [[1, (), ()], [(), (), ()], [(), (), ()]
    

    它也比使用范围稍微快一点。从 ipython 外壳:

    In [1]: timeit P = [ [()]*3 for i in range(3) ]
    1000000 loops, best of 3: 1.41 us per loop
    
    In [2]: timeit P=[i[:] for i in [[()]*3]*3]
    1000000 loops, best of 3: 1.27 us per loop
    

    【讨论】:

      【解决方案4】:

      实际上是相同的内部列表(相同的引用)被重复了 3 次,所以当你修改其中任何一个时,你实际上是在修改所有这些。

      因此,内部列表[()]*3 生成一个包含三个元组的列表。但是这个列表被重复了三遍。然而,在python中,它实际上是一个被相乘的引用列表,所以引用是重复的,但每个引用仍然指向同一个底层列表。

      【讨论】:

        猜你喜欢
        • 2016-10-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-18
        • 2017-07-26
        • 1970-01-01
        • 2016-12-28
        • 1970-01-01
        相关资源
        最近更新 更多