だから私はlist
オブジェクトで遊んでいて、list
がlist()
で作成された場合、リストの理解よりも多くのメモリを使用するという奇妙なことを見つけましたか?私はPython 3.5.2を使用しています
_In [1]: import sys
In [2]: a = list(range(100))
In [3]: sys.getsizeof(a)
Out[3]: 1008
In [4]: b = [i for i in range(100)]
In [5]: sys.getsizeof(b)
Out[5]: 912
In [6]: type(a) == type(b)
Out[6]: True
In [7]: a == b
Out[7]: True
In [8]: sys.getsizeof(list(b))
Out[8]: 1008
_
docs から:
リストはいくつかの方法で作成できます:
- 空のリストを示すために角括弧のペアを使用する:_
[]
_- 角括弧を使用して、コンマで項目を区切ります:_
[a]
_、_[a, b, c]
_- リスト内包表記の使用:_
[x for x in iterable]
_- 型コンストラクターの使用:
list()
またはlist(iterable)
しかし、list()
を使用すると、より多くのメモリを使用するようです。
そして、list
が大きいほど、ギャップは大きくなります。
なぜこれが起こるのですか?
更新#1
Python 3.6.0b2でテスト:
_Python 3.6.0b2 (default, Oct 11 2016, 11:52:53)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getsizeof(list(range(100)))
1008
>>> sys.getsizeof([i for i in range(100)])
912
_
更新#2
Python 2.7.12:
_Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.getsizeof(list(xrange(100)))
1016
>>> sys.getsizeof([i for i in xrange(100)])
920
_
すばらしいPythonを理解するのを手伝ってくれてありがとう。
そんなに大掛かりな質問をしたくはありません(なぜ答えを投稿しているのか)、自分の考えを見せて共有したいだけです。
@ ReutSharabani のように正しく記述されています: "list()は決定的にリストサイズを決定します"。そのグラフから見ることができます。
append
を使用するとき、またはリストの内包表記を使用するときは、何らかのポイントに達すると常に何らかの境界が広がります。 list()
を使用すると、ほぼ同じ境界がありますが、それらは浮いています。
[〜#〜] update [〜#〜]
@ ReutSharabani 、 @ tavo 、 @ SvenFestersen に感謝
要約すると、list()
はリストのサイズに応じてメモリを事前に割り当てますが、リストの内包表記はそれを行うことができません(.append()
のように、必要に応じて追加のメモリを要求します)。 list()
がより多くのメモリを保存する理由です。
list()
事前割り当てメモリを示すもう1つのグラフ。そのため、緑色の線はlist(range(830))
が要素ごとに追加され、しばらくの間メモリが変化しないことを示しています。
更新2
@Barmarが以下のコメントで述べたように、list()
はリストの内包表記よりも速くなければならないので、長さlist
からnumber=1000
から4**0
までの4**10
でtimeit()
を実行しました。