Aparentemente list(a)
, o macacão não é atribuído, o [x for x in a]
macacão em alguns pontos e o [*a]
macacão o tempo todo ?
Aqui estão os tamanhos n de 0 a 12 e os tamanhos resultantes em bytes para os três métodos:
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
Computado assim, reproduzível em repl.it , usando Python 3. 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]))
Então, como isso funciona? Como o [*a]
globalocate? Na verdade, qual mecanismo ele usa para criar a lista de resultados a partir da entrada fornecida? Ele usa um iterador a
e usa algo comolist.append
? Onde está o código fonte?
( Colab com dados e código que produziu as imagens.)
Aumentando o zoom para n menor:
Diminuindo o zoom para n maior:
list(a)
opera inteiramente em C; ele pode alocar o nó do buffer interno por nó à medida que itera a
. [x for x in a]
apenas usa LIST_APPEND
muito, de modo que segue o padrão normal de "alocar um pouco, realocar quando necessário" de uma lista normal. [*a]
usa BUILD_LIST_UNPACK
, o que ... Eu não sei o que isso faz, além de aparentemente
list(a)
e [*a]
são idênticos, e a localização geral comparada a [x for x in a]
, então ... sys.getsizeof
pode não ser a ferramenta certa a ser usada aqui.
sys.getsizeof
é a ferramenta certa, apenas mostra que list(a)
costumava ser usada em geral. Na verdade, o que há de novo no Python 3.8 menciona: "O construtor da lista não atribui [...] globalmente" .
[*a]
parece se comportar como o usoextend
em uma lista vazia.