В чем разница между функциями range и xrange в Python 2.X?
Проблема заключается в том, что я заметил, что xrange работает быстрее, чем range, но не понимаю, почему это так. У меня нет никаких доказательств, кроме слухов, подтверждающих, что xrange действительно быстрее. Можете объяснить, в чем отличие между следующими конструкциями и почему одна из них может быть более эффективной?
for i in range(0, 20):
pass # ваш код здесь
for i in xrange(0, 20):
pass # ваш код здесь
5 ответ(ов)
В Python 2.x:
rangeсоздает список, поэтому если вы выполнитеrange(1, 10000000), будет создан список в памяти с9999999элементами.xrange— это объект последовательности, который выполняется лениво.
В Python 3:
rangeвыполняет ту же функцию, что иxrangeв Python 2. Чтобы получить список, вам нужно явно использоватьlist(range(...)).xrangeбольше не существует.
В Python 2 функция range создает список, поэтому при выполнении range(1, 10000000) в памяти будет создан список с 9999999 элементами. В то время как xrange является генератором (или, точнее, последовательным объектом), который вычисляется "лениво", то есть значения создаются по мере необходимости.
Это верно, но в Python 3 функция range() реализована аналогично xrange() из Python 2. Если вам действительно нужно создать список, вам следует воспользоваться следующим кодом:
list(range(1, 100))
Таким образом, range() в Python 3 позволяет вам работать с диапазоном чисел, не загружая все значения в память одновременно, а только по мере необходимости.
Не забывайте использовать модуль 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 есть ограничение: аргументы 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, но без ограничений по минимальным и максимальным значениям.
xrange возвращает итератор и хранит в памяти только одно число за раз, в то время как range сохраняет весь список чисел в памяти. Это означает, что xrange более эффективен с точки зрения использования памяти, особенно при работе с большими диапазонами. Если вам нужно итерироваться по числам, выбирайте xrange (в Python 2) или range (в Python 3), который также ведет себя как итератор и требует меньше памяти, чем range в Python 2.
Есть ли эквивалент функции range(12) из Python в C#?
Как получить индекс в цикле 'for'?
UnicodeEncodeError: 'ascii' кодек не может закодировать символ u'\xa0' на позиции 20: номер не в диапазоне (128)
IndentationError: неверный отступ, не соответствует ни одному уровню внешнего отступа, хотя отступ выглядит корректно
Вывод списка в обратном порядке с помощью функции range()