8

В чем разница между функциями range и xrange в Python 2.X?

20

Проблема заключается в том, что я заметил, что xrange работает быстрее, чем range, но не понимаю, почему это так. У меня нет никаких доказательств, кроме слухов, подтверждающих, что xrange действительно быстрее. Можете объяснить, в чем отличие между следующими конструкциями и почему одна из них может быть более эффективной?

for i in range(0, 20):
    pass  # ваш код здесь

for i in xrange(0, 20):
    pass  # ваш код здесь

5 ответ(ов)

10

В Python 2.x:

  • range создает список, поэтому если вы выполните range(1, 10000000), будет создан список в памяти с 9999999 элементами.
  • xrange — это объект последовательности, который выполняется лениво.

В Python 3:

  • range выполняет ту же функцию, что и xrange в Python 2. Чтобы получить список, вам нужно явно использовать list(range(...)).
  • xrange больше не существует.
2

В Python 2 функция range создает список, поэтому при выполнении range(1, 10000000) в памяти будет создан список с 9999999 элементами. В то время как xrange является генератором (или, точнее, последовательным объектом), который вычисляется "лениво", то есть значения создаются по мере необходимости.

Это верно, но в Python 3 функция range() реализована аналогично xrange() из Python 2. Если вам действительно нужно создать список, вам следует воспользоваться следующим кодом:

list(range(1, 100))

Таким образом, range() в Python 3 позволяет вам работать с диапазоном чисел, не загружая все значения в память одновременно, а только по мере необходимости.

1

Не забывайте использовать модуль 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() будет обеспечивать удобное поведение итераторов в любом случае.

0

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

xrange(2**32-1, 2**32+1)  # Если long составляет 32 бита, возникает OverflowError: Python int слишком велик, чтобы быть сконвертированным в C long
range(2**32-1, 2**32+1)   # OK --> [4294967295L, 4294967296L]

Обратите внимание, что в Python 3.0 осталась только функция range, которая ведет себя как xrange из версии 2.x, но без ограничений по минимальным и максимальным значениям.

0

xrange возвращает итератор и хранит в памяти только одно число за раз, в то время как range сохраняет весь список чисел в памяти. Это означает, что xrange более эффективен с точки зрения использования памяти, особенно при работе с большими диапазонами. Если вам нужно итерироваться по числам, выбирайте xrange (в Python 2) или range (в Python 3), который также ведет себя как итератор и требует меньше памяти, чем range в Python 2.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь