Я вижу, что они дают одинаковый результат, разница в скорости? Почему две функции для одного и того же?
> range(5)
[0, 1, 2, 3, 4]
>>> xrange(5)
xrange(5)
>>> for i in range(5):
... print i
...
0
1
2
3
4
>>> for i in xrange(5):
... print i
...
0
1
2
3
4
Да,
range
иxrange
они дают тот же результат, но по-разному.Базы
Как вы уже догадались, функция
range
возвращает список:Функция диапазона будет занимать объем памяти в соответствии с размером диапазона, который вы передаете ей в качестве параметра.
С другой стороны, функция
xrange
возвращает свой собственный тип данных xrange-type :Ну, за
xrange
, на самом деле, нет никакой разницыrange
с точки зрения производительности, преимущество в том, чтоxrange
он всегда будет занимать один и тот же объем памяти (ОЗУ) независимо от размера диапазона:Короче говоря, конечной целью обеих функций является возврат списков, но можно сказать, что
xrange
они делают это по запросу из-за своей «ленивой» природы.Итераторы
В обоих случаях поддерживается протокол итерации, поскольку оба имеют метод
__iter__
:Таким образом, следующие случаи эквивалентны:
То же самое относится к
xr
. Большая разница в том, что когда вы выполняете итерациюr
, вы делаете это по списку, который уже был ранее оценен (и загружен в память), а при итерацииxr
вы делаете это по «ленивому» списку, который передает вам значения как они вам нужны (загрузка в память по одному).Теперь это может не иметь особого смысла с диапазоном из 10 целых чисел, но попробуйте это с несколькими миллионами, и вы заметите разницу в вашей оперативной памяти.
генераторы
Я знаю, что это не часть исходного вопроса, но мне показалось уместным добавить его к ответу, поскольку генераторы - это объекты, которые, наконец, реализуют протокол итерации.
Они похожи на списки, но создаются с использованием круглых скобок вместо квадратных.
Примеры:
Теперь генераторы работают аналогичным образом,
xrange
поскольку они также «ленивы» и возвращают значение только до тех пор, пока оно вам нужно, не загружая все в память с помощью выраженияyield
.использованная литература
Функция
range
генерирует внутренний временный список, которым манипулируют поэлементно,xrange
создавая интератор (определяет интерфейс для обхода совокупности элементов и доступа к ним, так что клиенту не нужно знать подробности и он может обрабатывать их в любом случае), которые можно пройти без затрат на то, что может быть большим временным объектом списка.Пример:
Остановитесь
x
наrange(10000)
: он сгенерирует список из 10 тысяч элементов, а затем будет проходить по каждому из них по очереди.For
x
inxrange(10000)
: будет генерировать 10 тысяч целых чисел одно за другим, передавая каждое из них переменной x по очереди.Ссылка
В python2 это разные функции и их мелкие отличия довольно хорошо объясняются в документации по xrange : он
xrange
генерирует объект xrange , а онrange
генерирует список. Преимущество объектаXRange
в том, что ему не нужно генерировать все элементы до тех пор, пока это не потребуется, что означает значительную экономию ресурсов. Кроме того, в реализации CPython (которая является наиболее распространенной из python) этот тип циклов может быть оптимизирован гораздо лучше и проще.В Python3 больше нет двух функций, объединенных в одну функцию
range
, которая была бы эквивалентнаxrange
функции python2. Для получения списка необходимо вызвать конструктор списка (например:list(range(1000))
)