답변:
Python 2.x에서 :
range
리스트를 생성하므로, 그렇게하면 range(1, 10000000)
리스트를 메모리에리스트로 생성합니다 9999999
.
xrange
느리게 평가되는 시퀀스 객체입니다.
파이썬 3에서는 range
python 's와 동일 xrange
하며 목록을 얻으려면을 사용해야 list(range(...))
합니다.
xrange(x).__iter__()
발전기입니다.
i
이 초기화가 아니라 요청시 평가됨을 의미합니다 .
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()
python -m timeit "for i in xrange(1000000):" " pass"
the extra overhead is only 0.04 seconds
그것을 보는 올바른 방법 (90.5-51.1)/51.1 = 1.771 times slower
이 아닙니다. 이것이 프로그램의 핵심 루프 인 경우 잠재적으로 병목 현상을 일으킬 수 있음을 전달하기 때문에 정확합니다. 그러나 이것이 작은 부분이라면 1.77x는 그리 많지 않습니다.
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에는 range
2.x xrange
만 있고 최소 및 최대 끝점에 대한 제한이없는 것처럼 작동합니다 .
Library Reference 와 함께 시간을 보내십시오 . 익숙할수록 이와 같은 질문에 대한 답변을 더 빨리 찾을 수 있습니다. 내장 객체와 유형에 관한 처음 몇 장이 특히 중요합니다.
xrange 유형의 장점은 xrange 객체가 나타내는 범위의 크기에 관계없이 항상 동일한 양의 메모리를 사용한다는 것입니다. 일관된 성능 이점이 없습니다.
파이썬 구문에 대한 빠른 정보를 찾는 또 다른 방법은 docstring과 help-function입니다.
print xrange.__doc__ # def doc(x): print x.__doc__ is super useful
help(xrange)
나는 아무도 문서를 읽지 않는다는 충격을 받았다 .
이 함수는와 매우 유사
range()
하지만xrange
목록 대신 객체를 반환 합니다. 이것은 실제로 모두 동시에 저장하지 않고 해당 목록과 동일한 값을 생성하는 불투명 시퀀스 유형입니다. 의 장점xrange()
이상은range()
최소한 (때문에xrange()
범위의 모든 요소는 루프가있는 경우로서 (사용되지 않는 경우 매우 큰 범위의 메모리가 부족한 시스템에서 사용 또는 경우를 제외하고 그들에게 물었을 때 여전히 가치를 창출 할 수있다) 일반적으로)로 끝납니다break
.
이 간단한 예제에서 xrange
over 의 장점을 찾을 수 있습니다 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
기능 의 구현은 Python-2의 구현과 동일 하지만 Python-3에서는 xrange
제거되었습니다 xrange
.
행복한 코딩 !!
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
루프를 사용할 때 큰 차이는 없지만 인쇄 만하면 차이가 있습니다!
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
다른 답변 중 일부는 파이썬 3 2.X의를 제거 언급 range
하고 2.X의 개명 xrange
에 range
. 그러나 3.0 또는 3.1을 사용하지 않는 한 (아무도 없어야 함) 실제로는 약간 다른 유형입니다.
3.1 문서에서 말한 것처럼 :
범위 객체는 동작이 거의 없습니다. 인덱싱, 반복 및
len
함수 만 지원합니다 .
그러나 3.2+에서는 range
전체 시퀀스입니다. 확장 슬라이스 및와 collections.abc.Sequence
동일한 의미를 갖는 모든 방법을 지원 합니다 list
. *
그리고 적어도 CPython 및 PyPy (현재 존재하는 유일한 두 개의 3.2 이상 구현)에서는 index
and count
메소드와 in
연산자 (정수만 전달하는 한)의 상수 시간 구현 도 있습니다. 이것은 쓰기 123456 in r
가 3.2+에서 합리적이고 2.7 또는 3.1에서는 끔찍한 아이디어라는 것을 의미합니다.
* 2.6-2.7 및 3.0-3.1에서 issubclass(xrange, collections.Sequence)
반환 되는 사실 은 3.2에서 수정되었고 백 포트되지 않은 버그 입니다.True
파이썬 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)
xrange()
발전기가 아닙니다. xrange(n)
.__ iter __ ()`입니다.
루프에서 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?
또는 for 루프에서 xrange를 사용하십시오.
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의 느린 인스턴스에 대한 의견이 있습니까? 또는 더 나은 예 :-)
xrange
Python 3에서는 비교가 중복되었지만 약간 더 빨랐습니다.
timeit
을위한 것입니다. 여러 번 실행하고 GC를 비활성화하고 대신 가장 좋은 시계를 사용하는 time
등 의 작업 을 처리합니다.
파이썬에서 xrange ()와 range ()는 user와 비슷하게 작동하지만 두 함수를 사용하여 메모리가 어떻게 할당되는지에 대해 이야기 할 때 차이점이 있습니다.
range ()를 사용할 때 생성하는 모든 변수에 메모리를 할당하므로 더 큰 no와 함께 사용하지 않는 것이 좋습니다. 생성 될 변수
반면에 xrange ()는 한 번에 특정 값만 생성하며 필요한 모든 값을 인쇄하기 위해 for 루프와 함께 만 사용할 수 있습니다.
뭐?
range
런타임시 정적 목록을 반환합니다. 필요할 때마다 값이 생성되는 (생성기는 아니지만 생성기처럼 작동)를
xrange
반환 object
합니다.
언제 사용합니까?
xrange
특히 휴대폰과 같은 "메모리 감지 시스템"이있는 경우 10 억과 같은 거대한 범위의 목록을 생성하려는 경우에 .range
목록을 여러 번 반복 하려면 사용하십시오 .추신 : Python 3.x의 range
기능 == Python 2.x의 xrange
기능.
xrange
생성기 객체를 반환하지 않습니다.
모두가 그것을 크게 설명했습니다. 그러나 나는 그것을 직접보고 싶었습니다. python3을 사용합니다. 그래서 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 ()'로 바꿉니다.
도움 문서에서.
파이썬 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.
파이썬 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 객체를 반환합니다.
파이썬 3.x의에서 range
이된다 xrange
파이썬 2.x에서의, 그리고 xrange
제거됩니다.
0-N 항목의 스캔 / 인쇄 요구 사항에서 range 및 xrange는 다음과 같이 작동합니다.
range ()-메모리에 새 목록을 만들고 0에서 N까지의 전체 항목 (전체적으로 N + 1)을 가져 와서 인쇄합니다. xrange ()-항목을 스캔하고 현재 발견 된 항목 만 메모리에 유지하는 반복자 인스턴스를 작성하므로 항상 동일한 양의 메모리를 사용합니다.
필요한 요소가 목록의 시작 부분에있는 경우 상당한 시간과 메모리를 절약합니다.
xrange
반복자 인스턴스를 작성하지 않습니다. 그것은 생성 xrange
반복 가능하다 객체를하지만, 목록 좋아하지 반복자-거의 (그러나 확실히) 시퀀스.
범위 는 목록 을 반환 하지만 xrange 는 범위 크기에 관계없이 동일한 메모리를 사용 하는 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 % 더 효율적입니다.
range()
파이썬에서 2.x
이 함수는 본질적으로 range()
Python에서 사용할 수 있었던 이전 함수이며 지정된 범위의 요소를 포함 2.x
하는 list
객체 의 인스턴스를 반환합니다 .
그러나이 구현은 숫자 범위가있는 목록을 초기화 할 때 너무 비효율적입니다. 예를 들어, for i in range(1000000)
메모리에이 목록을 저장해야하므로 메모리 및 시간 사용량 측면에서 실행하는 데 비용이 많이 드는 명령입니다.
range()
파이썬 3.x
과 xrange()
파이썬2.x
파이썬 3.x
은 새로운 구현을 도입했습니다 range()
(새로운 구현은 이미 Python을 2.x
통해 사용할 수 있었지만xrange()
함수를 ).
이 range()
공격은 게으른 평가 라는 전략을 이용합니다 . 대신 범위에있는 요소의 거대한 목록을 만드는, 새로운 구현 클래스 소개 range
, 지정된 범위에서 필요한 요소를 나타내는 경량 객체를 메모리에 명시 적으로 저장하지 않고 (이 발전기처럼 들릴 수도 있지만 게으른 평가의 개념은 다른).
예를 들어 다음을 고려하십시오.
# Python 2.x
>>> a = range(10)
>>> type(a)
<type 'list'>
>>> b = xrange(10)
>>> type(b)
<type 'xrange'>
과
# Python 3.x
>>> a = range(10)
>>> type(a)
<class 'range'>
이 게시물 보기범위와 xrange의 차이점을 찾으려면 을 .
인용 :
range
0으로 시작하는 정의 된 길이의 연속 정수 목록을 정확하게 반환합니다xrange
. 그러나 "xrange object"를 반환합니다 .이 반복자는 반복자와 같은 역할을합니다.
xrange
반복자가 아닙니다. 에 의해 반환 된 range
목록은 반복을 지원합니다 (목록은 반복 가능한 프로토 타입 예제입니다). 전체적인 이점은 xrange
"최소한"것이 아닙니다. 등등.