798

どうやら xrange の方が高速ですが、なぜ高速なのかわかりません (これまでのところ、逸話以外に高速であるという証拠はありません)、またはそれ以外に何が違うのですか?

for i in range(0, 20):
for i in xrange(0, 20):
4

28 に答える 28

941

Python 2.x の場合:

  • rangeリストを作成するため、これを行うと、要素を含むrange(1, 10000000)リストがメモリ内に作成されます。9999999

  • xrange遅延評価するシーケンス オブジェクトです。

Python 3 では:

  • rangePython 2 のxrange. リストを取得するには、明示的に を使用する必要がありますlist(range(...))
  • xrangeもはや存在しない。
于 2008-09-18T17:55:13.913 に答える
235

range はリストを作成するため、これを行うと、要素を含むrange(1, 10000000)リストがメモリ内に作成されます。9999999

xrange はジェネレーターなので、遅延評価するシーケンス オブジェクトです。

これは本当ですが、Python 3 ではrange()、Python 2 によって実装されxrange()ます。実際にリストを生成する必要がある場合は、次のことを行う必要があります。

list(range(1,100))
于 2008-09-18T18:08:19.110 に答える
118

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()

于 2008-09-18T22:11:15.530 に答える
69

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が、最小および最大のエンドポイントに制限がないことに注意してください。

于 2008-09-18T18:13:44.180 に答える
42

xrange は反復子を返し、一度に 1 つの数値のみをメモリに保持します。range は、数値のリスト全体をメモリに保持します。

于 2008-09-18T17:55:00.140 に答える
32

Library Referenceに時間を割いてください。慣れれば慣れるほど、このような質問に対する答えをより早く見つけることができます。特に重要なのは、組み込みオブジェクトと型に関する最初の数章です。

xrange 型の利点は、xrange オブジェクトが表す範囲のサイズに関係なく、常に同じ量のメモリを使用することです。一貫したパフォーマンス上の利点はありません。

Python コンストラクトに関する簡単な情報を見つけるもう 1 つの方法は、docstring と help-function です。

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
于 2008-09-18T17:55:59.137 に答える
17

ドキュメントには次のように明確に記載されています。

この関数は とよく似ていますが、リストではなくオブジェクトをrange()返します。xrangeこれは、対応するリストと同じ値を生成する不透明なシーケンス型であり、実際にはすべてを同時に格納する必要はありません。xrange()overの利点range()は最小限です (xrange()要求されたときに値を作成する必要があるため) メモリが不足しているマシンで非常に大きな範囲が使用されている場合、または範囲のすべての要素が使用されていない場合 (ループが使用されている場合など) を除きます。通常は ) で終了しbreakます。

于 2014-04-07T06:25:25.353 に答える
14

rangeはリストを作成するため、range(1、10000000)を実行すると、メモリ内に10000000要素のリストが作成されます。xrangeはジェネレーターであるため、遅延評価します。

これには2つの利点があります。

  1. を取得せずに、より長いリストを繰り返すことができますMemoryError
  2. 各数値を遅延的に解決するため、反復を早期に停止すれば、リスト全体を作成する時間を無駄にすることはありません。
于 2008-09-18T18:44:38.647 に答える
12

これは最適化のためです。

range() は、最初から最後まで値のリストを作成します (例では 0 .. 20)。これは、非常に大きな範囲ではコストのかかる操作になります。

一方、xrange() はより最適化されています。必要な場合にのみ次の値を計算し (xrange シーケンス オブジェクトを介して)、 range() のようにすべての値のリストを作成しません。

于 2008-09-18T17:59:46.040 に答える
10

range(x,y)forループを使用すると、x と y の間の各数値のリストが返されrangeます。実際、rangeより大きなインデックス範囲を持っています。range(x.y)x と y の間のすべての数値のリストを出力します

xrange(x,y)戻りますが、ループxrange(x,y)を使用した場合はより高速です。より小さなインデックス範囲を持っています。印刷するだけでなく、そこにあるすべての数字を保持します。forxrangexrangexrangexrange(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

ループを使用するときは大きな違いはありませんが、印刷するだけでは違いがあります!

于 2016-07-12T00:05:27.750 に答える
6

ループで 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 の遅いインスタンスについて何かコメントはありますか? またはより良い例:-)

于 2011-03-18T12:04:59.797 に答える
4

Python の xrange() と range() は user と同様に機能しますが、両方の関数を使用してメモリがどのように割り当てられるかについて話しているときに違いが生じます。

range() を使用している場合、生成するすべての変数にメモリを割り当てるため、より大きな no で使用することはお勧めしません。生成される変数の。

一方、xrange() は一度に特定の値のみを生成し、必要なすべての値を出力するために for ループでのみ使用できます。

于 2016-01-19T12:48:45.973 に答える
3

range はリスト全体を生成して返します。xrange はそうではありません -- 必要に応じてリスト内の数値を生成します。

于 2008-09-18T17:55:27.330 に答える
2

何?
range実行時に静的リストを返します。必要に応じて値が生成される (ジェネレーターのように機能しますが、ジェネレーターではないことは確かです) を
xrange返します。object

いつどれを使う?

  • 特に携帯電話のような「メモリに敏感なシステム」を使用xrangeしている場合に、巨大な範囲、たとえば 10 億のリストを生成する場合に使用します。
  • rangeリストを数回繰り返したい場合に使用します。

PS: Python 3.x のrange機能 == Python 2.x のxrange機能。

于 2014-11-26T08:18:28.763 に答える
2

xrange は反復子を使用し (その場で値を生成します)、range はリストを返します。

于 2008-09-18T17:55:30.933 に答える
1

0-N 個の項目のスキャン/印刷の要件では、range と xrange は次のように機能します。

range() - メモリ内に新しいリストを作成し、0 から N 個の項目全体 (合計 N+1) を取得して出力します。xrange() - アイテムをスキャンし、現在検出されたアイテムのみをメモリに保持するイテレータ インスタンスを作成するため、常に同じ量のメモリを使用します。

必要な要素がリストの先頭にある場合のみ、時間とメモリを大幅に節約できます。

于 2014-01-15T12:45:29.323 に答える
1

range :-range はすべてを一度に入力します。つまり、範囲のすべての数値がメモリを占有します。

xrange :-xrange はジェネレーターのようなものです。数値の範囲が必要な場合に画像に表示されますが、for ループで使用する場合のように、それらを保存したくない場合など、メモリ効率が高くなります。

于 2017-01-10T06:00:16.390 に答える
-1

range と xrange の違いを見つけるには、この投稿を参照してください。

引用するには:

rangeはあなたの考えを正確に返します: 0xrangeで始まる定義された長さの連続した整数のリスト。ただし、イテレータのように機能する「xrange オブジェクト」を返します

于 2008-09-18T17:54:40.467 に答える