どうやら xrange の方が高速ですが、なぜ高速なのかわかりません (これまでのところ、逸話以外に高速であるという証拠はありません)、またはそれ以外に何が違うのですか?
for i in range(0, 20):
for i in xrange(0, 20):
どうやら xrange の方が高速ですが、なぜ高速なのかわかりません (これまでのところ、逸話以外に高速であるという証拠はありません)、またはそれ以外に何が違うのですか?
for i in range(0, 20):
for i in xrange(0, 20):
Python 2.x の場合:
range
リストを作成するため、これを行うと、要素を含むrange(1, 10000000)
リストがメモリ内に作成されます。9999999
xrange
遅延評価するシーケンス オブジェクトです。
Python 3 では:
range
Python 2 のxrange
. リストを取得するには、明示的に を使用する必要がありますlist(range(...))
。xrange
もはや存在しない。range はリストを作成するため、これを行うと、要素を含む
range(1, 10000000)
リストがメモリ内に作成されます。9999999
xrange
はジェネレーターなので、遅延評価するシーケンス オブジェクトです。
これは本当ですが、Python 3 ではrange()
、Python 2 によって実装されxrange()
ます。実際にリストを生成する必要がある場合は、次のことを行う必要があります。
list(range(1,100))
timeit
モジュールを使用して、コードの小さなスニペットのどれがより高速かをテストすることを忘れないでください!
$ python -m timeit 'for i in range(1000000):' ' pass'
10 loops, best of 3: 90.5 msec per loop
$ python -m timeit 'for i in xrange(1000000):' ' pass'
10 loops, best of 3: 51.1 msec per loop
個人的には、非常に巨大なリストを扱っていない限り、私は常に を使用します。ご覧のように、100 万エントリのリストの場合、余分なオーバーヘッドはわずか 0.04 秒ですrange()
。Corey が指摘しているように、Python 3.0 では廃止され、いずれにしても優れたイテレータの動作が提供されます。xrange()
range()
xrange
範囲パラメータのみを保存し、オンデマンドで数値を生成します。ただし、PythonのC実装では、現在、引数がClongに制限されています。
xrange(2**32-1, 2**32+1) # When long is 32 bits, OverflowError: Python int too large to convert to C long
range(2**32-1, 2**32+1) # OK --> [4294967295L, 4294967296L]
Python 3.0にはrange
、2.xのように動作するだけですxrange
が、最小および最大のエンドポイントに制限がないことに注意してください。
xrange は反復子を返し、一度に 1 つの数値のみをメモリに保持します。range は、数値のリスト全体をメモリに保持します。
Library Referenceに時間を割いてください。慣れれば慣れるほど、このような質問に対する答えをより早く見つけることができます。特に重要なのは、組み込みオブジェクトと型に関する最初の数章です。
xrange 型の利点は、xrange オブジェクトが表す範囲のサイズに関係なく、常に同じ量のメモリを使用することです。一貫したパフォーマンス上の利点はありません。
Python コンストラクトに関する簡単な情報を見つけるもう 1 つの方法は、docstring と help-function です。
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
ドキュメントには次のように明確に記載されています。
この関数は とよく似ていますが、リストではなくオブジェクトを
range()
返します。xrange
これは、対応するリストと同じ値を生成する不透明なシーケンス型であり、実際にはすべてを同時に格納する必要はありません。xrange()
overの利点range()
は最小限です (xrange()
要求されたときに値を作成する必要があるため) メモリが不足しているマシンで非常に大きな範囲が使用されている場合、または範囲のすべての要素が使用されていない場合 (ループが使用されている場合など) を除きます。通常は ) で終了しbreak
ます。
rangeはリストを作成するため、range(1、10000000)を実行すると、メモリ内に10000000要素のリストが作成されます。xrangeはジェネレーターであるため、遅延評価します。
これには2つの利点があります。
MemoryError
。これは最適化のためです。
range() は、最初から最後まで値のリストを作成します (例では 0 .. 20)。これは、非常に大きな範囲ではコストのかかる操作になります。
一方、xrange() はより最適化されています。必要な場合にのみ次の値を計算し (xrange シーケンス オブジェクトを介して)、 range() のようにすべての値のリストを作成しません。
range(x,y)
for
ループを使用すると、x と y の間の各数値のリストが返されrange
ます。実際、range
より大きなインデックス範囲を持っています。range(x.y)
x と y の間のすべての数値のリストを出力します
xrange(x,y)
戻りますが、ループxrange(x,y)
を使用した場合はより高速です。より小さなインデックス範囲を持っています。印刷するだけでなく、そこにあるすべての数字を保持します。for
xrange
xrange
xrange
xrange(x,y)
[In] range(1,10)
[Out] [1, 2, 3, 4, 5, 6, 7, 8, 9]
[In] xrange(1,10)
[Out] xrange(1,10)
for
ループを使用すると、機能します
[In] for i in range(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
[In] for i in xrange(1,10):
print i
[Out] 1
2
3
4
5
6
7
8
9
ループを使用するときは大きな違いはありませんが、印刷するだけでは違いがあります!
ループで xrange に対して range をテストすると ( timeit を使用する必要があることはわかっていますが、これは単純なリスト内包表記の例を使用してメモリからすばやくハッキングされました)、次のことがわかりました。
import time
for x in range(1, 10):
t = time.time()
[v*10 for v in range(1, 10000)]
print "range: %.4f" % ((time.time()-t)*100)
t = time.time()
[v*10 for v in xrange(1, 10000)]
print "xrange: %.4f" % ((time.time()-t)*100)
これは次を与えます:
$python range_tests.py
range: 0.4273
xrange: 0.3733
range: 0.3881
xrange: 0.3507
range: 0.3712
xrange: 0.3565
range: 0.4031
xrange: 0.3558
range: 0.3714
xrange: 0.3520
range: 0.3834
xrange: 0.3546
range: 0.3717
xrange: 0.3511
range: 0.3745
xrange: 0.3523
range: 0.3858
xrange: 0.3997 <- garbage collection?
または、for ループで xrange を使用します。
range: 0.4172
xrange: 0.3701
range: 0.3840
xrange: 0.3547
range: 0.3830
xrange: 0.3862 <- garbage collection?
range: 0.4019
xrange: 0.3532
range: 0.3738
xrange: 0.3726
range: 0.3762
xrange: 0.3533
range: 0.3710
xrange: 0.3509
range: 0.3738
xrange: 0.3512
range: 0.3703
xrange: 0.3509
私のスニペットは適切にテストされていますか? xrange の遅いインスタンスについて何かコメントはありますか? またはより良い例:-)
Python の xrange() と range() は user と同様に機能しますが、両方の関数を使用してメモリがどのように割り当てられるかについて話しているときに違いが生じます。
range() を使用している場合、生成するすべての変数にメモリを割り当てるため、より大きな no で使用することはお勧めしません。生成される変数の。
一方、xrange() は一度に特定の値のみを生成し、必要なすべての値を出力するために for ループでのみ使用できます。
range はリスト全体を生成して返します。xrange はそうではありません -- 必要に応じてリスト内の数値を生成します。
何?
range
実行時に静的リストを返します。必要に応じて値が生成される (ジェネレーターのように機能しますが、ジェネレーターではないことは確かです) を
xrange
返します。object
いつどれを使う?
xrange
している場合に、巨大な範囲、たとえば 10 億のリストを生成する場合に使用します。range
リストを数回繰り返したい場合に使用します。PS: Python 3.x のrange
機能 == Python 2.x のxrange
機能。
xrange は反復子を使用し (その場で値を生成します)、range はリストを返します。
0-N 個の項目のスキャン/印刷の要件では、range と xrange は次のように機能します。
range() - メモリ内に新しいリストを作成し、0 から N 個の項目全体 (合計 N+1) を取得して出力します。xrange() - アイテムをスキャンし、現在検出されたアイテムのみをメモリに保持するイテレータ インスタンスを作成するため、常に同じ量のメモリを使用します。
必要な要素がリストの先頭にある場合のみ、時間とメモリを大幅に節約できます。
range :-range はすべてを一度に入力します。つまり、範囲のすべての数値がメモリを占有します。
xrange :-xrange はジェネレーターのようなものです。数値の範囲が必要な場合に画像に表示されますが、for ループで使用する場合のように、それらを保存したくない場合など、メモリ効率が高くなります。
range と xrange の違いを見つけるには、この投稿を参照してください。
引用するには:
range
はあなたの考えを正確に返します: 0xrange
で始まる定義された長さの連続した整数のリスト。ただし、イテレータのように機能する「xrange オブジェクト」を返します