code

Python 2.X에서 범위와 xrange 함수의 차이점은 무엇입니까?

codestyles 2020. 9. 30. 10:45
반응형

Python 2.X에서 범위와 xrange 함수의 차이점은 무엇입니까?


분명히 xrange가 더 빠르지 만 왜 더 빠른지 (그리고 지금까지 더 빠르다는 증거 외에는 증거가 없음) 또는 그 외에 무엇이 다른지 모르겠습니다.

for i in range(0, 20):
for i in xrange(0, 20):

Python 2.x에서 :

  • range목록을 생성하므로 그렇게하면 요소가 range(1, 10000000)있는 메모리에 목록이 생성 9999999됩니다.

  • xrange 느리게 평가되는 시퀀스 객체입니다.

Python 3에서는 rangepython의 xrange를 수행하며 목록을 가져 오려면 list(range(...)).


범위는 목록을 생성하므로 그렇게하면 요소가 range(1, 10000000)있는 메모리에 목록이 생성 9999999됩니다.

xrange 생성기이므로 느리게 평가 되는 시퀀스 객체 입니다 .

이것은 사실이지만 Python 3에서는 .range()Python 2로 구현됩니다 .xrange(). 실제로 목록을 생성해야하는 경우 다음을 수행해야합니다.

list(range(1,100))

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 초에 불과합니다. Corey가 지적했듯이 Python 3.0에서는 사라지고 어쨌든 멋진 반복기 동작을 제공 할 것입니다..xrange().range()


xrange범위 매개 변수 만 저장하고 요청시 숫자를 생성합니다. 그러나 Python의 C 구현은 현재 인수를 C long으로 제한합니다.

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에는 range2.x와 같이 동작 xrange하지만 최소 및 최대 끝점에 대한 제한이 없습니다.


xrange는 반복자를 반환하고 한 번에 하나의 숫자 만 메모리에 보관합니다. 범위는 전체 숫자 목록을 메모리에 유지합니다.


Library Reference 와 함께 시간을 보내십시오 . 익숙할수록 이와 같은 질문에 대한 답을 더 빨리 찾을 수 있습니다. 특히 중요한 것은 내장 객체와 유형에 대한 처음 몇 장입니다.

xrange 유형의 장점은 xrange 객체가 나타내는 범위의 크기에 관계없이 항상 동일한 양의 메모리를 사용한다는 것입니다. 일관된 성능 이점이 없습니다.

파이썬 구조에 대한 빠른 정보를 찾는 또 다른 방법은 독 스트링과 도움말 함수입니다.

print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)

range는 목록을 생성하므로 range (1, 10000000)을 수행하면 10000000 요소가있는 메모리에 목록이 생성됩니다. xrange는 생성기이므로 느리게 평가됩니다.

이는 두 가지 이점을 제공합니다.

  1. .NET Framework를 가져 오지 않고도 더 긴 목록을 반복 할 수 있습니다 MemoryError.
  2. 각 숫자를 느리게 해결하므로 반복을 일찍 중지하면 전체 목록을 만드는 데 시간을 낭비하지 않습니다.

아무도 문서를 읽지 않았다는 것에 충격을 받았습니다 .

이 함수는와 매우 유사 range()하지만 xrange목록 대신 객체를 반환 합니다. 이것은 불투명 시퀀스 유형으로, 실제로 동시에 모두 저장하지 않고 해당 목록과 동일한 값을 생성합니다. 의 장점 xrange()이상은 range()최소한 (때문에 xrange()범위의 모든 요소는 루프가있는 경우로서 (사용되지 않는 경우 매우 큰 범위의 메모리가 부족한 시스템에서 사용 또는 경우를 제외하고 그들에게 물었을 때 여전히 가치를 창출 할 수있다) 일반적으로)로 끝납니다 break.


최적화 이유입니다.

range ()는 처음부터 끝까지 값 목록을 만듭니다 (예시에서는 0 .. 20). 이것은 매우 넓은 범위에서 비용이 많이 드는 작업이 될 것입니다.

반면에 xrange ()는 훨씬 더 최적화되어 있습니다. (xrange 시퀀스 객체를 통해) 필요할 때만 다음 값을 계산하고 range ()와 같은 모든 값의 목록을 생성하지 않습니다.


이 간단한 예제에서 xrangeover 의 이점을 찾을 수 있습니다 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.NET과 비교하여 정말 느린 다음 사례를 살펴보십시오 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기능 구현은 Python-2의 구현과 동일 하지만 Python-3에서는 xrange제거되었습니다 xrange.

행복한 코딩 !!


range () : range (1, 10)은 1에서 10까지의 숫자 목록을 반환하고 전체 목록을 메모리에 보관합니다.

xrange () : range ()와 비슷하지만 목록을 반환하는 대신 요청시 범위의 숫자를 생성하는 객체를 반환합니다. 루핑의 경우 range ()보다 약간 빠르고 메모리 효율성이 높습니다. xrange () 객체를 반복자처럼 만들고 필요에 따라 숫자를 생성합니다. (Lazy Evaluation)

In [1]: range(1,10)

Out[1]: [1, 2, 3, 4, 5, 6, 7, 8, 9]

In [2]: xrange(10)

Out[2]: xrange(10)

In [3]: print xrange.__doc__

xrange([start,] stop[, step]) -> xrange object

range(x,y)for루프 를 사용하는 경우 x와 y 사이의 각 숫자 목록을 반환하면 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

루프를 사용할 때 큰 차이는 없지만 인쇄 만하면 차이가 있습니다!


파이썬 2.x에서

range (x) 는 x 요소로 메모리에 생성 된 목록을 반환합니다.

>>> a = range(5)
>>> a
[0, 1, 2, 3, 4]

xrange (x) 는 요청시 숫자를 생성하는 생성자 obj 인 xrange 객체를 반환합니다. for-loop (Lazy Evaluation) 중에 계산됩니다.

루핑의 경우 range ()보다 약간 빠르며 메모리 효율성이 더 높습니다.

>>> b = xrange(5)
>>> b
xrange(5)

When testing range against xrange in a loop (I know I should use timeit, but this was swiftly hacked up from memory using a simple list comprehension example) I found the following:

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)

which gives:

$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?

Or, using xrange in the for loop:

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

Is my snippet testing properly? Any comments on the slower instance of xrange? Or a better example :-)


Some of the other answers mention that Python 3 eliminated 2.x's range and renamed 2.x's xrange to range. However, unless you're using 3.0 or 3.1 (which nobody should be), it's actually a somewhat different type.

As the 3.1 docs say:

Range objects have very little behavior: they only support indexing, iteration, and the len function.

However, in 3.2+, range is a full sequence—it supports extended slices, and all of the methods of collections.abc.Sequence with the same semantics as a list.*

And, at least in CPython and PyPy (the only two 3.2+ implementations that currently exist), it also has constant-time implementations of the index and count methods and the in operator (as long as you only pass it integers). This means writing 123456 in r is reasonable in 3.2+, while in 2.7 or 3.1 it would be a horrible idea.


* The fact that issubclass(xrange, collections.Sequence) returns True in 2.6-2.7 and 3.0-3.1 is a bug that was fixed in 3.2 and not backported.


xrange() and range() in python works similarly as for the user , but the difference comes when we are talking about how the memory is allocated in using both the function.

When we are using range() we allocate memory for all the variables it is generating, so it is not recommended to use with larger no. of variables to be generated.

xrange() on the other hand generate only a particular value at a time and can only be used with the for loop to print all the values required.


range generates the entire list and returns it. xrange does not -- it generates the numbers in the list on demand.


xrange uses an iterator (generates values on the fly), range returns a list.


What?
range returns a static list at runtime.
xrange returns an object (which acts like a generator, although it's certainly not one) from which values are generated as and when required.

When to use which?

  • Use xrange if you want to generate a list for a gigantic range, say 1 billion, especially when you have a "memory sensitive system" like a cell phone.
  • Use range if you want to iterate over the list several times.

PS: Python 3.x's range function == Python 2.x's xrange function.


On a requirement for scanning/printing of 0-N items , range and xrange works as follows.

range() - creates a new list in the memory and takes the whole 0 to N items(totally N+1) and prints them. xrange() - creates a iterator instance that scans through the items and keeps only the current encountered item into the memory , hence utilising same amount of memory all the time.

In case the required element is somewhat at the beginning of the list only then it saves a good amount of time and memory.


The difference decreases for smaller arguments to 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

In this case xrange(100) is only about 20% more efficient.


Everyone has explained it greatly. But I wanted it to see it for myself. I use python3. So, I opened the resource monitor (in Windows!), and first, executed the following command first:

a=0
for i in range(1,100000):
    a=a+i

and then checked the change in 'In Use' memory. It was insignificant. Then, I ran the following code:

for i in list(range(1,100000)):
    a=a+i

And it took a big chunk of the memory for use, instantly. And, I was convinced. You can try it for yourself.

If you are using Python 2X, then replace 'range()' with 'xrange()' in the first code and 'list(range())' with 'range()'.


Range returns a list while xrange returns an xrange object which takes the same memory irrespective of the range size,as in this case,only one element is generated and available per iteration whereas in case of using range, all the elements are generated at once and are available in the memory.


range :-range will populate everything at once.which means every number of the range will occupy the memory.

xrange :-xrange is something like generator ,it will comes into picture when you want the range of numbers but you dont want them to be stored,like when you want to use in for loop.so memory efficient.


From the help docs.

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

Difference is apparent. In Python 2.x, range returns a list, xrange returns an xrange object which is iterable.

In Python 3.x, range becomes xrange of Python 2.x, and xrange is removed.


Additionally, if do list(xrange(...)) will be equivalent to range(...).

So list is slow.

Also xrange really doesn't fully finish the sequence

So that's why its not a list, it's a xrange object


See this post to find difference between range and xrange:

To quote:

range returns exactly what you think: a list of consecutive integers, of a defined length beginning with 0. xrange, however, returns an "xrange object", which acts a great deal like an iterator

참고URL : https://stackoverflow.com/questions/94935/what-is-the-difference-between-range-and-xrange-functions-in-python-2-x

반응형