何がoverallocateに[* A]原因は?

ステファンPochmann:

どうやらlist(a)、overallocateない[x for x in a]いくつかの点でoverallocatesは、と[*a]overallocates すべての時間を

N = 100までのサイズ

ここでは三つの方法のためにサイズ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で再現可能パイソン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]overallocate?実際には、どのようなメカニズムには、与えられた入力から結果リストを作成するために使用しますか?それはオーバーイテレータ使用していますaのようなものと使用をlist.appendソースコードはどこですか?

データとコードとのコラボ画像を生成しました。)

小さいnまでにズーム:

N = 40までのサイズ

大きなnにズームアウト:

N = 1000までのサイズ

ShadowRanger:

[*a] 内部での同等のCをやっています

  1. 新しいを作成し、空 list
  2. コール newlist.extend(a)
  3. 戻り値list

あなたがテストにを展開するのであれば:

from sys import getsizeof

for n in range(13):
    a = [None] * n
    l = []
    l.extend(a)
    print(n, getsizeof(list(a)),
             getsizeof([x for x in a]),
             getsizeof([*a]),
             getsizeof(l))

オンラインそれをお試しください!

あなたはのために結果が表示されますgetsizeof([*a])l = []; l.extend(a); getsizeof(l)同じです。

これは通常行うには正しいことです。ときextendINGのあなたは、通常より後で追加するには期待している、と同様に一般開梱のためには、複数のものが次々に追加されることを想定しています。[*a]通常のケースではありません。それに追加される複数のアイテムまたはイテレート可能オブジェクトが存在する前提list(は[*a, b, c, *d])ので、割り当て超過は、一般的なケースでの作業を保存します。

By contrast, a list constructed from a single, presized iterable (with list()) may not grow or shrink during use, and overallocating is premature until proven otherwise; Python recently fixed a bug that made the constructor overallocate even for inputs with known size.

As for list comprehensions, they're effectively equivalent to repeated appends, so you're seeing the final result of the normal overallocation growth pattern when adding an element at a time.

明確にするために、これのどれも言語保証するものではありません。それはCPythonのは、それを実装して、どれだけです。Python言語仕様は、一般的に、特定の成長パターンと無関心されるlist(保証償却別にO(1) appendS及びpop端からS)。コメントで述べたように、具体的な実装は3.9で再び変更します。それは影響しません一方で[*a]、それはビルド一時的に使用されるどのような他の例影響を与える可能性がありtuple、個々のアイテムのとextendではtuple、それは今の複数のアプリケーションになっLIST_APPEND割り当て超過が発生し、どのような数字は計算に入ったときに変更することができ、。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=27865&siteId=1
おすすめ