Python: 分配多个嵌套列表的最短方法是什么

Python: What's the shortest way to assign multiple nested lists

我有不同的嵌套列表:

a = [[] for e in range(6)]
b = [[] for e in range(6)]
c = [[] for e in range(6)]

鉴于这些列表具有相似的结构,是否可以同时(在一行中)分配它们? 我正在考虑像这样开始的事情:

a, b, c = [[] for e in range(6)] ...?...

我正在使用 Python 3

您可以滥用生成器和元组解包:

a, b, c = ([[] for e in range(6)] for _ in range(3))

让我们确保 abc 不引用相同的列表:

a[0].append(1)
b[0].append(2)
c[0].append(3)
print(a)
print(b)
print(c)

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

Python有一种机制让多个变量引用同一个对象,其中:

a = b = c = [[] for e in range(6)]

但您可能不希望这样,因为现在 abc 指的是同一个列表。因此,如果我们附加到 a,那么该更改也会反映在 bc.

然而,我们可以使用 iterable 解包:

a, b, c = <b>[</b>[[] for e in range(6)] <b>for _ in range(3)]</b>

所以这里我们构造一个包含三个列表的列表,然后我们解压这个列表在三个变量中,这样每个变量都有自己的子列表。

或者一般来说,如果你有某个表达式需要求值n次,然后赋值给n个变量,你可以使用:

x<i>1</i>, x<i>2</i>, x<i>n</i> = [<i><expr></i> for _ in range(<i>n</i>)]

这里<expr>当然要换成真正的表达式,变量x<i>i</i> 有实变量。

复制列表怎么样?不是很对称,但它有效...

a = [[] for e in range(6)]
b, c = a[:], a[:]
assert a == b and a == c and b == c

正如@vaultah 指出的,这不是深拷贝:嵌套列表是共享的:

a[2].append(1)
assert a == b and a == c and b == c

import copy
b, c = copy.deepcopy(a), copy.deepcopy(a)

a[2].append(1)
assert a != b and a != c and b == c

尝试深度复制:

from copy import deepcopy
a = [[] for e in range(6)]

b=deepcopy(a)
c=deepcopy(a)

为什么深拷贝为什么不拷贝:

原因如下:

如果你使用简单副本,那么如果你修改原始副本,它将修改复制的嵌套列表,因为它是浅副本

from copy import deepcopy
a = [[] for e in range(6)]

b=a[:]
c=a[:]

for i in a:
    i.append(22)

print(a)

print(b,c)

输出:

[[22], [22], [22], [22], [22], [22]]
[[22], [22], [22], [22], [22], [22]] [[22], [22], [22], [22], [22], [22]]

但是使用 deepcopy :

from copy import deepcopy
a = [[] for e in range(6)]

b=deepcopy(a)
c=deepcopy(a)

for i in a:
    i.append(22)

print(a)

print(b,c)

输出:

[[22], [22], [22], [22], [22], [22]]
[[], [], [], [], [], []] [[], [], [], [], [], []]