显然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
在空列表中使用。