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 a
e 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_APPEND
molto, 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.getsizeof
non potrebbe essere lo strumento giusto da utilizzare qui.
sys.getsizeof
sia 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 diextend
un elenco vuoto.