В чем разница между функциями range и xrange в Python 2.X?
по-видимому, xrange быстрее, но я понятия не имею, почему это быстрее (и никаких доказательств, кроме анекдотического до сих пор, что это быстрее) или что кроме этого отличается от
for i in range(0, 20):
for i in xrange(0, 20):
28 ответов
range создает список, поэтому, если вы это сделаете range(1, 10000000)
создает список в памяти с 9999999
элементы.
xrange
- объект последовательности, который оценивает лениво.
следует добавить из подсказки @Thiago, что в python3 диапазон эквивалентен xrange
range создает список, поэтому, если вы делаете
range(1, 10000000)
создает список в памяти с9999999
элементы.
xrange
- это генератор, так чтообъект последовательностиэточто оценивает лениво.
Это правда, но в Python 3 диапазон будет реализован Python 2 xrange(). Если вам нужно создать список, вам нужно будет сделать:
list(range(1,100))
помните, использовать модуль раз все проверить, какие из малых snipps кода быстрее!
$ 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 исчезнет, и диапазон все равно даст вам хорошее поведение итератора.
xrange
сохраняет только параметры диапазона и генерирует числа по требованию. Однако реализация C Python в настоящее время ограничивает свои args 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 возвращает итератор и сохраняет только одно число в памяти за раз. range хранит весь список чисел в памяти.
проведите некоторое время с Справочник По Библиотеке. Чем больше вы с ним знакомы, тем быстрее сможете найти ответы на подобные вопросы. Особенно важны первые несколько глав о встроенных объектах и типах.
преимуществом типа xrange является то, что объект xrange всегда будет взять тот же объем памяти, независимо от размера круга, который он представляет. Нет последовательной работы преимущества.
другой способ найти быструю информацию о конструкции Python-это docstring и help-function:
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
range () vs xrange () в python:
range() и xrange () - это две функции, которые можно использовать для итерации определенного количества раз в циклах for в Python. В Python 3 нет xrange, но функция range ведет себя как xrange в Python 2.Если вы хотите написать код, который будет работать на Python 2 и Python 3, Вы должны использовать Range().
1. Тип Возврата:
range () возвращает - список как тип возврата.
xrange() возвращает – объект xrange ().
# initializing a with range()
a = range(1,10000)
# initializing a with xrange()
x = xrange(1,10000)
# testing the type of a
print ("The return type of range() is : ")
print (type(a))
# testing the type of x
print ("The return type of xrange() is : ")
print (type(x))
выход :
The return type of range() is :
<type 'list'>
The return type of xrange() is :
<type 'xrange'>
2. Память:
переменная, хранящая диапазон, созданный range () занимает больше памяти по сравнению с переменной, хранящей диапазон с помощью xrange (). Основной причиной этого является возвращаемый тип range () - list и xrange () - объект xrange ().
# initializing a with range()
a = range(1,10000)
# initializing a with xrange()
x = xrange(1,10000)
# testing the size of a
print ("The size allotted using range() is : ")
print (sys.getsizeof(a))
# testing the size of a
print ("The size allotted using xrange() is : ")
print (sys.getsizeof(x))
выход :
The size allotted using range() is :
80064
The size allotted using xrange() is :
40
3. Использование операций :
поскольку range () возвращает список, все операции, которые могут быть применены к списку, могут быть использованы на нем. С другой стороны, поскольку xrange() возвращает объект xrange, операции, связанные с list, не могут быть применены к ним, следовательно, недостаток.
# Python code to demonstrate range() vs xrange()
# on basis of operations usage
# initializing a with range()
a = range(1,6)
# initializing a with xrange()
x = xrange(1,6)
# testing usage of slice operation on range()
print ("The list after slicing using range is : ")
print (a[2:5])
# testing usage of slice operation on xrange()
print ("The list after slicing using xrange is : ")
print (x[2:5])
выход :
The list after slicing using range is :
[3, 4, 5]
The list after slicing using xrange is :
Traceback (most recent call last):
File "pp.py", line 18, in <module>
print (x[2:5])
TypeError: sequence index must be integer, not 'slice'
4. Скорость:
из-за того, что xrange() оценивает только объект генератора, содержащий только значения, необходимые для ленивой оценки, поэтому быстрее в реализации, чем range().
Важные Моменты :
- если вы хотите написать код, который будет работать на Python 2 и Python 3, Используйте range (), поскольку функция xrange устарела в Python 3.
- range () быстрее, если итерация по одной и той же последовательности несколько раз.
- xrange () должен каждый раз восстанавливать целочисленный объект, но range () будет иметь реальные целочисленные объекты. (Он всегда будет выполнять хуже с точки зрения памяти, однако).
range создает список, поэтому, если вы делаете range (1, 10000000), он создает список в памяти с 10000000 элементами. xrange-это генератор, поэтому он лениво оценивает.
это дает два преимущества:
- вы можете повторять более длинные списки, не получая
MemoryError
. - как он решает каждое число лениво, если вы остановите итерацию рано, вы не будете тратить время на создание всего списка.
Я в шоке, что никто не читал doc:
эта функция очень похожа на
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
Удачи В Кодировании!!
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]
xrange (x) возвращает объект xrange, который является генератором obj, который генерирует числа по требованию. они вычисляются во время for-loop(ленивая оценка).
для зацикливания, это немного быстрее, чем Range() и оперативную память.
>>> b = xrange(5)
>>> b
xrange(5)
при тестировании диапазона против xrange в цикле (я знаю, что я должен использовать timeit, но это было быстро взломано из памяти, используя простой пример понимания списка) я нашел следующее:
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.х range
и переименован в 2.х xrange
to range
. Однако, если вы не используете 3.0 или 3.1 (чего не должно быть), это на самом деле несколько другой тип.
As 3.1 docs говорят:
объекты диапазона имеют очень мало поведения: они поддерживают только индексирование, итерацию и .
однако, в 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 () мы выделяем память для всех переменных, которые он генерирует, поэтому не рекомендуется использовать с большим no. переменных, которые будут сгенерированы.
xrange (), с другой стороны, генерирует только определенное значение за раз и может использоваться только с циклом for для печати все необходимые значения.
range генерирует весь список и возвращает его. xrange не делает-он генерирует числа в списке по требованию.
что?range
возвращает статический список во время выполнения.xrange
возвращает object
(который действует как генератор, хотя он, конечно, не один), из которого значения генерируются по мере необходимости.
когда какую использовать?
- использовать
xrange
Если вы хотите создать список для гигантского диапазона, скажем, 1 миллиард, особенно когда у вас есть" чувствительная к памяти система", такая как мобильный телефон. - использовать
range
Если вы хотите перебирать список несколько раз.
PS: Python 3.х range
функция = = Python 2.х
по требованию для сканирования / печати 0-N элементов, диапазон и 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% более эффективное.
все объяснили это очень. Но я хотел, чтобы он увидел это сам. Я использую питон3. Итак, я открыл Монитор ресурсов (в 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
удалены.
посмотреть этот в должности чтобы найти разницу между диапазоном и xrange:
цитата:
range
возвращает именно то, что вы думаете: список подряд целые числа определенной длины, начинающиеся с 0.xrange
, однако, возвращает "объект xrange", который действует очень похоже на итератор