В чем разница между функциями 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.
Как получить индекс в цикле 'for'?
UnicodeEncodeError: 'ascii' кодек не может закодировать символ u'\xa0' на позиции 20: номер не в диапазоне (128)
Как использовать десятичное значение шага в range()?
IndentationError: неверный отступ, не соответствует ни одному уровню внешнего отступа, хотя отступ выглядит корректно
Как лучше всего удалить акценты (нормализовать) в строке Unicode Python?