Anscheinend list(a)
nicht zuordnen, [x for x in a]
an einigen Stellen insgesamt [*a]
zuordnen und die ganze Zeit insgesamt zuordnen ?
Hier sind die Größen n von 0 bis 12 und die resultierenden Größen in Bytes für die drei Methoden:
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
So berechnet , reproduzierbar bei repl.it mit 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]))
Also: Wie funktioniert das? Wie [*a]
ordnet man insgesamt zu? Welchen Mechanismus verwendet es tatsächlich, um die Ergebnisliste aus der angegebenen Eingabe zu erstellen? Verwendet es einen Iterator a
und verwendet so etwas wie list.append
? Wo ist der Quellcode?
( Colab mit Daten und Code , die die Bilder erzeugt haben.)
Vergrößern auf kleiner n:
Verkleinern auf größer n:
list(a)
arbeitet vollständig in C; Es kann den internen Puffer Knoten für Knoten zuweisen, während er iteriert a
. [x for x in a]
verwendet nur LIST_APPEND
viel, so folgt es dem normalen Muster "Gesamt ein wenig zuordnen, bei Bedarf neu zuweisen" einer normalen Liste. [*a]
verwendet BUILD_LIST_UNPACK
, die ... Ich weiß nicht, was das tut, außer anscheinend die ganze Zeit zu
list(a)
und [*a]
identisch sind und beide im Vergleich zu insgesamt zugeordnet sind [x for x in a]
, sodass ... sys.getsizeof
möglicherweise nicht das richtige Werkzeug für die Verwendung ist.
sys.getsizeof
ist das richtige Tool, es zeigt nur, dass list(a)
für die Gesamtzuordnung verwendet. Eigentlich Was ist neu in Python 3.8 erwähnt es: „Die Liste Konstruktor nicht overallocate [...]“ .
[*a]
so zu verhalten scheint, als würde manextend
eine leere Liste verwenden.