Python列表乘法:[[...]]*3使3个列表在修改时相互镜像

KFL*_*KFL 35 python list multiplication

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

>>> P = [ [()]*3 ]*3
>>> P
[[(), (), ()], [(), (), ()], [(), (), ()]]
>>> P[0][0]=1
>>> P
[[1, (), ()], [1, (), ()], [1, (), ()]]
Run Code Online (Sandbox Code Playgroud)

Ign*_*ams 28

您已对同一列表进行了3次引用.

>>> a = b = []
>>> a.append(42)
>>> b
[42]
Run Code Online (Sandbox Code Playgroud)

你想这样做:

P = [[()] * 3 for x in range(3)]
Run Code Online (Sandbox Code Playgroud)


ick*_*fay 7

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

P = [ [()]*3 for i in range(3) ]
Run Code Online (Sandbox Code Playgroud)


Joh*_*ooy 6

你也可以像这样写它,它具有显示结构的优点 [[()]*3]*3

>>> P=[i[:] for i in [[()]*3]*3]
>>> P[0][0]=1
>>> P
[[1, (), ()], [(), (), ()], [(), (), ()]
Run Code Online (Sandbox Code Playgroud)

它也比使用范围稍快.来自ipython shell:

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
Run Code Online (Sandbox Code Playgroud)


dhg*_*dhg 5

它实际上是相同的内部列表(相同的引用),重复3次,所以当你修改它们中的任何一个时,实际上你正在修改它们.

因此,内部列表[()]*3生成三个元组的列表.但此列表重复三次.但是,在python中,它实际上是一个被乘法的引用列表,因此引用是重复的,但每个引用仍然指向相同的基础列表.