Tampaknya list(a)
tidak secara keseluruhan, [x for x in a]
keseluruhan di beberapa titik, dan [*a]
keseluruhan sepanjang waktu ?
Berikut adalah ukuran n dari 0 hingga 12 dan ukuran yang dihasilkan dalam byte untuk tiga metode:
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
Dihitung seperti ini, dapat direproduksi di repl.it , menggunakan 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]))
Jadi: Bagaimana cara kerjanya? Bagaimana secara [*a]
keseluruhan? Sebenarnya, mekanisme apa yang digunakannya untuk membuat daftar hasil dari input yang diberikan? Apakah itu menggunakan iterator a
dan menggunakan sesuatu seperti list.append
? Di mana kode sumbernya?
( Colab dengan data dan kode yang menghasilkan gambar.)
Memperbesar menjadi lebih kecil n:
Perkecil hingga lebih besar n:
list(a)
beroperasi sepenuhnya dalam C; itu dapat mengalokasikan node buffer internal demi node saat iterates over a
. [x for x in a]
hanya menggunakan LIST_APPEND
banyak, jadi ini mengikuti pola "secara keseluruhan sedikit, alokasikan kembali jika perlu" dari daftar normal. [*a]
menggunakan BUILD_LIST_UNPACK
, yang ... Saya tidak tahu apa yang dilakukannya, selain ternyata terlalu banyak mengalokasikan sepanjang waktu :)
list(a)
dan [*a]
identik, dan keduanya secara keseluruhan dibandingkan dengan [x for x in a]
, jadi ... sys.getsizeof
mungkin bukan alat yang tepat untuk digunakan di sini.
sys.getsizeof
adalah alat yang tepat, itu hanya menunjukkan bahwa list(a)
digunakan untuk mengatur keseluruhan. Sebenarnya Apa Yang Baru Di Python 3.8 menyebutkannya: "Daftar konstruktor tidak secara keseluruhan menempatkan [...]" .
[*a]
tampaknya berperilaku seperti menggunakanextend
daftar kosong.