Apparemment, list(a)
ne sur-utilise pas, sur- [x for x in a]
utilise à certains moments et sur- [*a]
utilise tout le temps ?
Voici les tailles n de 0 à 12 et les tailles résultantes en octets pour les trois méthodes:
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
Calculé comme ceci, reproductible sur repl.it , en utilisant 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]))
Donc comment ça fonctionne? Comment [*a]
surutilisation? En fait, quel mécanisme utilise-t-il pour créer la liste des résultats à partir de l'entrée donnée? Utilise-t-il un itérateur a
et utilise-t-il quelque chose comme list.append
? Où est le code source?
( Colab avec les données et le code qui ont produit les images.)
Zoom avant sur n plus petit:
Zoom arrière sur un n plus grand:
list(a)
fonctionne entièrement en C; il peut allouer le tampon interne nœud par nœud au fur et à mesure de son itération a
. [x for x in a]
utilise juste LIST_APPEND
beaucoup, donc il suit le modèle normal "surallouer un peu, réallouer si nécessaire" d'une liste normale. [*a]
utilise BUILD_LIST_UNPACK
, qui ... je ne sais pas ce que cela fait, à part apparemment
list(a)
et [*a]
soient identiques, et les deux surutilisent par rapport à [x for x in a]
, donc ... sys.getsizeof
pourrait ne pas être le bon outil à utiliser ici.
sys.getsizeof
c'est le bon outil, il montre juste que list(a)
utilisé pour sur-utiliser. En fait, Quoi de neuf en Python 3.8 le mentionne: "Le constructeur de liste ne sur-utilise pas [...]" .
[*a]
semble se comporter comme une utilisationextend
sur une liste vide.