どうやらlist(a)
、[x for x in a]
オーバーローケートしない、ある時点でオーバーローケートする、常に[*a]
オーバーローケートするのでしょうか。
以下は、0から12までのサイズnと、3つのメソッドの結果のバイト単位のサイズです。
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で再現可能パイソン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)
完全にCで動作します。反復するときに、内部バッファをノードごとに割り当てることができますa
。たくさん[x for x in a]
使用LIST_APPEND
するだけなので、通常のリストの「少し過剰に割り当て、必要に応じて再割り当て」という通常のパターンに従います。[*a]
を使用BUILD_LIST_UNPACK
しています。これはどうやったかわからないのですが、どうやら常にオーバーアロケーションしているようです。:)
list(a)
と[*a]
は同一であり、どちらもと比較して全体的に割り当てられている[x for x in a]
ようです。そのため、sys.getsizeof
ここでは適切なツールではない可能性があります。
sys.getsizeof
は正しいツールだと思います、それは単にlist(a)
全体的な割り当てに使用されたことを示しています。実際、Python 3.8の新機能では、「リストコンストラクターは割り当てられていない[...]」と述べています。
[*a]
するように動作extend
し、空のリストを使用するように動作するように見えます。