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))
让我们确保 a
、b
和 c
不引用相同的列表:
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)]
但您可能不希望这样,因为现在 a
、b
和 c
指的是同一个列表。因此,如果我们附加到 a
,那么该更改也会反映在 b
和 c
.
中
然而,我们可以使用 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]]
[[], [], [], [], [], []] [[], [], [], [], [], []]
我有不同的嵌套列表:
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))
让我们确保 a
、b
和 c
不引用相同的列表:
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)]
但您可能不希望这样,因为现在 a
、b
和 c
指的是同一个列表。因此,如果我们附加到 a
,那么该更改也会反映在 b
和 c
.
然而,我们可以使用 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]]
[[], [], [], [], [], []] [[], [], [], [], [], []]