Вопрос

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

for i in range(0, 20):
for i in xrange(0, 20):
Это было полезно?

Решение

диапазон создает список, поэтому, если вы сделаете range(1, 10000000) он создает список в памяти с помощью 9999999 элементы.

xrange это объект последовательности, который вычисляется лениво.

Следует добавить из подсказки @Thiago, что в python3 range выполняет эквивалент xrange в python

Другие советы

диапазон создает список, поэтому, если вы сделаете 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

Лично я всегда использую .range(), если только я не имел дело с в самом деле огромные списки - как вы можете видеть, с точки зрения времени, для списка из миллиона записей дополнительные накладные расходы составляют всего 0,04 секунды.И, как указывает Кори, в Python 3.0 .xrange() уйдет и .range() в любом случае это даст вам хорошее поведение итератора.

xrange сохраняет только параметры диапазона и генерирует числа по запросу.Однако реализация Python на C в настоящее время ограничивает свои аргументы C longs:

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 возвращает итератор и одновременно сохраняет в памяти только одно число.диапазон сохраняет весь список чисел в памяти.

Проведите некоторое время с Ссылка на библиотеку.Чем лучше вы с этим знакомы, тем быстрее сможете найти ответы на подобные вопросы.Особенно важны первые несколько глав о встроенных объектах и типах.

Преимущество типа xrange заключается в том, что объект xrange всегда будет занимать одинаковый объем памяти, независимо от размера диапазона, который он представляет.Нет никаких постоянных преимуществ в производительности.

Другим способом быстрого поиска информации о конструкции Python является строка документации и справочная функция:

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)

range создает список, поэтому, если вы используете range (1, 10000000), он создает список в памяти с 10000000 элементами.xrange - это генератор, поэтому он вычисляет лениво.

Это дает вам два преимущества:

  1. Вы можете перебирать более длинные списки, не получая MemoryError.
  2. Поскольку он лениво разрешает каждое число, если вы остановите итерацию раньше, вы не будете тратить время на создание всего списка.

Я потрясен, что никто не читал док:

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

Это делается по соображениям оптимизации.

range() создаст список значений от начала до конца (0 ..20 в вашем примере).Это станет дорогостоящей операцией на очень больших диапазонах.

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

Вы обнаружите преимущество xrange закончился range в этом простом примере:

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 4.49153590202 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    pass
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 7.04547905922 seconds

Приведенный выше пример не отражает ничего существенно лучшего в случае xrange.

Теперь рассмотрим следующий случай , когда range это действительно очень медленно, по сравнению с xrange.

import timeit

t1 = timeit.default_timer()
a = 0
for i in xrange(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer()

print "time taken: ", (t2-t1)  # 0.000764846801758 seconds

t1 = timeit.default_timer()
a = 0
for i in range(1, 100000000):
    if i == 10000:
        break
t2 = timeit.default_timer() 

print "time taken: ", (t2-t1)  # 2.78506207466 seconds

С range, он уже создает список от 0 до 100000000 (отнимает много времени), но xrange это генератор, и он генерирует числа только в зависимости от необходимости, то есть если итерация продолжается.

В Python-3 реализация range функциональность такая же, как у xrange в Python-2, в то время как они покончили с xrange в Python-3

Счастливого Кодирования!!

диапазон (): диапазон (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

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

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

В python 2.x

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

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

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

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

>>> b = xrange(5)
>>> b
xrange(5)

При тестировании range против xrange в цикле (я знаю, что должен использовать время пришло, но это было быстро вырезано из памяти с использованием простого примера понимания списка) Я нашел следующее:

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

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

Как документы 3.1 сказать:

Объекты диапазона имеют очень слабое поведение:они поддерживают только индексацию, итерацию и 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 и не перенесено обратно.

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

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

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

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

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

Диапазон Python Против xrange

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

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

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

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

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

Что касается требований к сканированию / печати 0-N элементов, range и xrange работают следующим образом.

range() - создает новый список в памяти и берет от 0 до N элементов (всего N + 1) и печатает их.xrange() - создает экземпляр итератора, который сканирует элементы и сохраняет в памяти только текущий обнаруженный элемент, следовательно, постоянно использует один и тот же объем памяти.

Только в том случае, если требуемый элемент находится в начале списка, это значительно экономит время и память.

Разница уменьшается при меньших аргументах до range(..) / xrange(..):

$ python -m timeit "for i in xrange(10111):" " for k in range(100):" "  pass"
10 loops, best of 3: 59.4 msec per loop

$ python -m timeit "for i in xrange(10111):" " for k in xrange(100):" "  pass"
10 loops, best of 3: 46.9 msec per loop

В данном случае xrange(100) это всего лишь примерно на 20% эффективнее.

Все прекрасно это объясняли.Но я хотел увидеть это своими глазами.Я использую python3.Итак, я открыл монитор ресурсов (в Windows!) и сначала выполнил следующую команду:

a=0
for i in range(1,100000):
    a=a+i

а затем проверил изменение в используемой памяти.Это было несущественно.Затем я запустил следующий код:

for i in list(range(1,100000)):
    a=a+i

И для этого мгновенно потребовался большой кусок памяти.И я был убежден.Вы можете попробовать это сами.

Если вы используете Python 2X, то замените 'range()' на 'xrange()' в первом коде и 'list(range())' на 'range()'.

Диапазон возвращает Список в то время как диапазон xrange возвращает диапазон xrange объект, который занимает одну и ту же память независимо от размера диапазона, поскольку в этом случае генерируется только один элемент и он доступен за итерацию, тогда как в случае использования диапазона все элементы генерируются одновременно и доступны в памяти.

диапазон: -диапазон заполнит все сразу.это означает, что каждое число диапазона будет занимать память.

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

Из справочных документов.

Python 2.7.12

>>> print range.__doc__
range(stop) -> list of integers
range(start, stop[, step]) -> list of integers

Return a list containing an arithmetic progression of integers.
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.
When step is given, it specifies the increment (or decrement).
For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!
These are exactly the valid indices for a list of 4 elements.

>>> print xrange.__doc__
xrange(stop) -> xrange object
xrange(start, stop[, step]) -> xrange object

Like range(), but instead of returning a list, returns an object that
generates the numbers in the range on demand.  For looping, this is 
slightly faster than range() and more memory efficient.

Python 3.5.2

>>> print(range.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object

Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step.  range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted!  range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).

>>> print(xrange.__doc__)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xrange' is not defined

Разница очевидна.В Python 2.x, range возвращает список, xrange возвращает объект xrange, который является итеративным.

В Python 3.x, range становится xrange из Python 2.x, и xrange удаляется.

Кроме того, если вы list(xrange(...)) будет эквивалентно range(...).

Итак list идет медленно.

Также xrange на самом деле это не полностью завершает последовательность

Так вот почему это не список, это xrange объект

Видишь это Публикация чтобы найти разницу между range и xrange:

Процитировать:

range возвращает именно то, что вы думаете:список последовательных целых чисел определенной длины, начинающихся с 0. xrange, однако возвращает "объект xrange", который действует во многом как итератор

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top