显然list(a)不是总归,[x for x in a]在某些时候[*a]总归,始终都是总归吗?
这是从0到12的大小n,以及三种方法的结果大小(以字节为单位):
0 56 56 56
1 64 88 88
2 72 88 96
3 80 88 104
4 88 88 112
5 96 120 120
6 104 120 128
7 112 120 136
8 120 120 152
9 128 184 184
10 136 184 192
11 144 184 200
12 152 184 208
这样计算,可以使用Python 3 在repl.it中重现。8:
from sys import getsizeof
for n in range(13):
a = [None] * n
print(n, getsizeof(list(a)),
getsizeof([x for x in a]),
getsizeof([*a]))
因此:这是如何工作的?如何整体化[*a]?实际上,它使用什么机制从给定的输入创建结果列表?它是否使用了迭代器a并使用了类似的东西list.append?源代码在哪里?
放大到较小的n:
缩小到较大的n:
list(a)完全在C中运行;它可以在迭代时逐个节点分配内部缓冲区a。[x for x in a]只是使用LIST_APPEND了很多东西,所以它遵循普通列表的正常“过度分配一点,必要时重新分配”的模式。[*a]使用BUILD_LIST_UNPACK,这...我不知道该怎么做,除了显然一直都在分配:)
list(a)和[*a]完全相同,并且与相比,二者总体上相同[x for x in a],因此... sys.getsizeof可能不是在此处使用的正确工具。
sys.getsizeof是正确的工具,它只是显示了list(a)用于整体化的工具。实际上,Python 3.8中的新增功能提到了这一点:“列表构造函数不会整体分配[...]”。



[*a]似乎表现为extend在空列表中使用。