Rõ ràng list(a)không phải là tổng thể, [x for x in a]tổng thể tại một số điểm, và [*a]tổng thể mọi lúc ?
Dưới đây là kích thước n từ 0 đến 12 và kích thước kết quả tính bằng byte cho ba phương thức:
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
Được tính toán như thế này, có thể tái tạo tại repl.it , sử dụng 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]))
Vì vậy, làm thế nào điều này làm việc? Làm thế nào để [*a]tổng thể? Trên thực tế, nó sử dụng cơ chế nào để tạo danh sách kết quả từ đầu vào đã cho? Nó sử dụng một iterator hơn avà sử dụng một cái gì đó như thế list.appendnào? Mã nguồn ở đâu?
( Colab với dữ liệu và mã tạo ra hình ảnh.)
Phóng to đến n nhỏ hơn:
Thu nhỏ đến n lớn hơn:
list(a)hoạt động hoàn toàn trong C; nó có thể phân bổ nút đệm nội bộ theo nút khi nó lặp lại a. [x for x in a]chỉ sử dụng LIST_APPENDrất nhiều, vì vậy nó tuân theo mô hình "tổng thể một chút, phân bổ lại khi cần thiết" của một danh sách bình thường. [*a]sử dụng BUILD_LIST_UNPACK, mà ... tôi không biết nó làm gì, ngoài việc phân bổ quá mức mọi lúc :)
list(a)và [*a]giống hệt nhau và cả hai tổng thể so với [x for x in a], vì vậy ... sys.getsizeofcó thể không phải là công cụ phù hợp để sử dụng ở đây.
sys.getsizeoflà công cụ phù hợp, nó chỉ hiển thị list(a)được sử dụng để tổng thể. Trên thực tế Có gì mới trong Python 3.8 đề cập đến nó: "Trình xây dựng danh sách không tổng thể [...]" .



[*a]dường như hoạt động như sử dụngextendtrong danh sách trống.