Мабуть list(a)
, не перенастроює, [x for x in a]
перераховує в деяких моментах і весь час[*a]
розміщує ?
Ось розміри n від 0 до 12 та отримані розміри в байтах для трьох методів:
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
Вираховано так, що відтворюється на repl.it , використовуючи 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]))
Отже: Як це працює? Як відбувається [*a]
перенапруження? Насправді, який механізм він використовує для створення списку результатів із заданого вводу? Чи використовує він ітератор a
і використовує щось подібне list.append
? Де вихідний код?
( Співпраця з даними та кодом, який створив зображення.)
Збільшення масштабу до меншої n:
Зменшення масштабу до n:
list(a)
працює повністю на С; він може виділяти внутрішній буферний вузол по вузлу в міру ітерації a
. [x for x in a]
просто використовує LIST_APPEND
багато, тому слід за звичайною схемою "перерозподілити трохи, перерозподілити, коли це необхідно" звичайного списку. [*a]
використання BUILD_LIST_UNPACK
, яке ... Я не знаю, що це робить, крім, мабуть,
list(a)
і [*a]
є ідентичними, і як overallocate по порівнянні з [x for x in a]
, так що ... sys.getsizeof
не може бути правильним інструментом для використання тут.
sys.getsizeof
це правильний інструмент, він просто показує, що list(a)
використовується для перенаселення. Насправді, що нового в Python 3.8 згадується про це: "Конструктор списку не переназначає [...]" .
[*a]
здається, веде себе як використанняextend
в порожньому списку.