sのメモリ割り当てのこの動作に困惑していますset
:
>>> set(range(1000)).__sizeof__()
32968
>>> set(range(1000)).union(range(1000)).__sizeof__() # expected, set doesn't change
32968
>>> set(range(1000)).union(list(range(1000))).__sizeof__() #expected, set doesn't change
32968
>>> set(range(1000)).union(set(range(1000))).__sizeof__() # not expected
65736
set
引数としてa を使用すると、結果として使用されるメモリ量が2 倍になるのはなぜset
ですか? どちらの場合も、結果は元のものと同じですset
。
>>> set(range(1000)) == set(range(1000)).union(range(1000)) == set(range(1000)).union(set(range(1000)))
True
通常のイテレータを使用しても同じことが起こることに注意してください。
>>> set(range(1000)).union(iter(list(range(1000)))).__sizeof__()
32968
update
メソッドを使用すると、次のようになります。
>>> a.update(range(1000))
>>> a.__sizeof__()
32968
>>> a.update(set(range(1000)))
>>> a.__sizeof__()
65736
最初は、 が呼び出されたときにunion
、もう一方のサイズがイテレータの場合は、単純にイテレータを実行し、要素を 1 つずつ追加します (すべての要素が既に にあるため、より多くのメモリを消費しません)。set
1000
set
set
しかしrange
もシーケンスでありlist
、最初の例の もそうです。
>>> len(range(1000))
1000
>>> range(1000)[100]
100
では、なぜこれは and では起こらずrange
、 でlist
のみ起こるのset
でしょうか? これの背後にある設計上の決定はありますか、それともバグですか?
Linux 64 ビットの python 2.7.3 および python 3.2.3 でテスト済み。