Apparentemente list(a)non sovrallocare, [x for x in a]sovrallocare in alcuni punti e [*a]sovrallocare continuamente ?
Ecco le dimensioni n da 0 a 12 e le dimensioni risultanti in byte per i tre metodi:
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
Calcolato in questo modo, riproducibile su 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]))
Quindi: come funziona? Come si [*a]sovrallocano? In realtà, quale meccanismo utilizza per creare l'elenco dei risultati dall'input specificato? Usa un iteratore sopra ae usa qualcosa di simile list.append? Dov'è il codice sorgente?
( Colab con dati e codice che ha prodotto le immagini.)
Zoom su n più piccolo:
Zoom indietro su n più grande:
list(a)opera interamente in C; può allocare il nodo buffer interno per nodo mentre scorre a. [x for x in a]usa solo LIST_APPENDmolto, quindi segue il normale schema "sovrallocare un po ', riallocare quando necessario" di un elenco normale. [*a]usa BUILD_LIST_UNPACK, che ... non so cosa faccia, tranne apparentemente sovra-allocare tutto il tempo :)
list(a)e [*a]sono identici, e sia overallocate confrontato [x for x in a], quindi ... sys.getsizeofnon potrebbe essere lo strumento giusto da utilizzare qui.
sys.getsizeofsia lo strumento giusto, mostra solo quello list(a)usato per sovrallocare. In realtà Novità di Python 3.8 lo menziona: "Il costruttore dell'elenco non sovrallocare [...]" .



[*a]sembra comportarsi come l'utilizzo diextendun elenco vuoto.