В чем разница между функциями range и xrange в Python 2.X? - PullRequest
662 голосов
/ 18 сентября 2008

Очевидно, xrange быстрее, но я понятия не имею, почему он быстрее (и нет никаких доказательств, кроме того, что он пока что быстрее), или что кроме этого отличается от

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

Ответы [ 28 ]

8 голосов
/ 23 июня 2015

range (): range (1, 10) возвращает список от 1 до 10 номеров и сохраняет весь список в памяти.

xrange (): Подобно range (), но вместо возврата списка возвращает объект, который генерирует числа в диапазоне по требованию. Для цикла это немного быстрее, чем range () и более эффективно использовать память. Объект xrange () похож на итератор и генерирует числа по запросу. (Ленивая оценка)

In [1]: range(1,10)

Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: xrange(10)

Out[2]: xrange(10)

In [3]: print xrange.__doc__

xrange([start,] stop[, step]) -> xrange object
8 голосов
/ 12 июля 2016

range(x,y) возвращает список каждого числа между x и y, если вы используете цикл for, тогда 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

При использовании петель нет большой разницы, хотя есть разница только при печати!

6 голосов
/ 28 февраля 2016

В питоне 2.х

range (x) возвращает список, созданный в памяти с элементами x.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange (x) возвращает объект xrange, который является генератором obj, который генерирует числа по запросу. они вычисляются во время цикла for (Lazy Evaluation).

Для циклов это немного быстрее, чем range () и более эффективное использование памяти.

>>> b = xrange(5)
>>> b
xrange(5)
5 голосов
/ 07 мая 2015

В некоторых других ответах упоминается, что Python 3 исключил 2.x range и переименовал 2.x xrange в range. Однако, если вы не используете 3.0 или 3.1 (что никто не должен делать), это на самом деле несколько другой тип.

Как 3,1 документа сказать:

Объекты Range имеют очень небольшое поведение: они поддерживают только индексирование, итерацию и функцию len.

Однако в 3.2+ range является полной последовательностью - она ​​поддерживает расширенные срезы и все методы collections.abc.Sequence с той же семантикой, что и list. *

И, по крайней мере, в CPython и PyPy (только две реализации 3.2+, которые существуют в настоящее время), он также имеет реализации с постоянным временем методов index и count и оператора in (до тех пор, пока Вы только передаете это целые числа). Это означает, что писать 123456 in r разумно в 3.2+, в то время как в 2.7 или 3.1 это было бы ужасной идеей.


* Тот факт, что issubclass(xrange, collections.Sequence) возвращает True в 2.6-2.7 и 3.0-3.1, является ошибкой , которая была исправлена ​​в 3.2 и не портирована.

5 голосов
/ 18 марта 2011

При тестировании диапазона против xrange в цикле (я знаю, что должен использовать 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?

Или, используя xrange в цикле for:

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? Или лучший пример: -)

4 голосов
/ 19 января 2016

xrange () и range () в python работают так же, как и для пользователя, но разница возникает, когда мы говорим о том, как выделяется память при использовании обеих функций.

Когда мы используем range (), мы выделяем память для всех переменных, которые он генерирует, поэтому не рекомендуется использовать с большим значением no. переменных, которые будут сгенерированы.

xrange (), с другой стороны, генерирует только определенное значение за раз и может использоваться только с циклом for для печати всех требуемых значений.

3 голосов
/ 18 сентября 2008
Диапазон

генерирует весь список и возвращает его. xrange не выполняет - генерирует числа в списке по запросу.

3 голосов
/ 01 августа 2015

Прочитайте следующий пост для сравнения диапазона и xrange с графическим анализом.

Диапазон Python против Xrange

2 голосов
/ 18 сентября 2008

xrange использует итератор (генерирует значения на лету), range возвращает список.

2 голосов
/ 26 ноября 2014

Что?
range возвращает статический список во время выполнения.
xrange возвращает object (который действует как генератор, хотя он определенно не один), из которого генерируются значения, когда и когда это требуется.

Когда использовать что?

  • Используйте xrange, если вы хотите создать список для гигантского диапазона, скажем, 1 миллиард, особенно если у вас есть «система, чувствительная к памяти», такая как мобильный телефон.
  • Используйте range, если вы хотите перебирать список несколько раз.

PS: функция Python 3.x range == функция Python 2.x xrange.

...