range ()보다 항상 xrange ()를 선호해야합니까?
그 이유는 무엇?
특히 넓은 범위에서 반복 할 때 성능 xrange()
이 더 좋습니다. 그러나 여전히 선호하는 몇 가지 경우가 있습니다 range()
.
파이썬 3에서,
range()
무엇을 수행xrange()
할 사용xrange()
존재하지 않습니다. Python 2와 Python 3 모두에서 실행될 코드를 작성하려면을 사용할 수 없습니다xrange()
.range()
어떤 경우에는 실제로 더 빠를 수 있습니다 (예 : 동일한 시퀀스를 여러 번 반복하는 경우xrange()
매번 정수 객체를 재구성해야하지만range()
실제 정수 객체를 갖습니다. (그러나 항상 메모리 측면에서 성능이 저하됩니다)xrange()
실제 목록이 필요한 모든 경우에 사용할 수 없습니다. 예를 들어 슬라이스 또는 목록 메소드를 지원하지 않습니다.
[편집] range()
2to3 도구로 업그레이드 하는 방법 을 언급하는 몇 가지 게시물 이 있습니다. 기록을 위해 다음의 일부 샘플 사용법에서 도구를 실행 한 결과는 다음 range()
과 같습니다.xrange()
RefactoringTool: Skipping implicit fixer: buffer
RefactoringTool: Skipping implicit fixer: idioms
RefactoringTool: Skipping implicit fixer: ws_comma
--- range_test.py (original)
+++ range_test.py (refactored)
@@ -1,7 +1,7 @@
for x in range(20):
- a=range(20)
+ a=list(range(20))
b=list(range(20))
c=[x for x in range(20)]
d=(x for x in range(20))
- e=xrange(20)
+ e=range(20)
보시다시피, for 루프 나 이해에 사용되거나 이미 list ()로 감싸 진 경우 범위는 변경되지 않습니다.
아니요, 둘 다 용도가 있습니다.
xrange()
메모리를 절약하므로 반복 할 때 사용하십시오 . 말하다:
for x in xrange(1, one_zillion):
오히려
for x in range(1, one_zillion):
반면에 range()
실제로 숫자 목록을 원할 경우 사용 하십시오.
multiples_of_seven = range(7,100,7)
print "Multiples of seven < 100: ", multiples_of_seven
당신은 선호합니다 range()
이상 xrange()
이 실제 목록이 필요합니다 경우에만 사용할 수 있습니다. 예를 들어에서 반환 한 목록을 수정하려는 경우 range()
또는 슬라이스하려는 경우가 있습니다. 반복 또는 심지어 정상적인 색인 xrange()
작업의 경우 잘 작동합니다 (보통 훨씬 더 효율적으로). 아주 작은 목록 range()
보다 약간 더 빠른 지점 이 xrange()
있지만 하드웨어 및 기타 다양한 세부 사항에 따라 손익분기 점은 길이 1 또는 2의 결과 일 수 있습니다. 걱정할 것이 없습니다. 선호 xrange()
합니다.
또 다른 차이점은 xrange ()는 C ints보다 큰 숫자를 지원할 수 없다는 것입니다. 따라서 파이썬의 많은 수의 지원을 사용하여 범위를 원하면 range ()를 사용해야합니다.
Python 2.7.3 (default, Jul 13 2012, 22:29:01)
[GCC 4.7.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> range(123456787676676767676676,123456787676676767676679)
[123456787676676767676676L, 123456787676676767676677L, 123456787676676767676678L]
>>> xrange(123456787676676767676676,123456787676676767676679)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C long
파이썬 3에는이 문제가 없습니다 :
Python 3.2.3 (default, Jul 14 2012, 01:01:48)
[GCC 4.7.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> range(123456787676676767676676,123456787676676767676679)
range(123456787676676767676676, 123456787676676767676679)
xrange()
객체 목록을 생성하는 대신 한 번에 하나의 객체 만 생성하기 때문에 더 효율적입니다. 100 개의 정수와 모든 오버 헤드와 그것들을 넣을 목록 대신 한 번에 하나의 정수만 있습니다. 더 빠른 생성, 더 나은 메모리 사용, 더 효율적인 코드.
내가 특별히 목록을 필요로하지 않는 한, 나는 항상 선호한다 xrange()
range ()는 목록을 반환하고 xrange ()는 xrange 객체를 반환합니다.
xrange ()는 약간 빠르며 약간 더 메모리 효율적입니다. 그러나 이익은 그리 크지 않습니다.
리스트가 사용하는 여분의 메모리는 물론 낭비되지 않고리스트는 더 많은 기능 (슬라이스, 반복, 삽입 등)을 갖습니다. 정확한 차이점은 설명서 에서 찾을 수 있습니다 . 기본 규칙이 없으므로 필요한 것을 사용하십시오.
Python 3.0은 아직 개발 중이지만 IIRC range ()는 xrange () 2.X와 매우 유사하며 list (range ())를 사용하여 목록을 생성 할 수 있습니다.
나는 슬라이스 및 인덱싱 기능을 가진 xrange 객체를 얻는 것이 그렇게 어렵지 않다고 말하고 싶습니다. 꽤 잘 작동하는 코드를 작성했으며 계산할 때 xrange만큼 빠릅니다 (반복).
from __future__ import division
def read_xrange(xrange_object):
# returns the xrange object's start, stop, and step
start = xrange_object[0]
if len(xrange_object) > 1:
step = xrange_object[1] - xrange_object[0]
else:
step = 1
stop = xrange_object[-1] + step
return start, stop, step
class Xrange(object):
''' creates an xrange-like object that supports slicing and indexing.
ex: a = Xrange(20)
a.index(10)
will work
Also a[:5]
will return another Xrange object with the specified attributes
Also allows for the conversion from an existing xrange object
'''
def __init__(self, *inputs):
# allow inputs of xrange objects
if len(inputs) == 1:
test, = inputs
if type(test) == xrange:
self.xrange = test
self.start, self.stop, self.step = read_xrange(test)
return
# or create one from start, stop, step
self.start, self.step = 0, None
if len(inputs) == 1:
self.stop, = inputs
elif len(inputs) == 2:
self.start, self.stop = inputs
elif len(inputs) == 3:
self.start, self.stop, self.step = inputs
else:
raise ValueError(inputs)
self.xrange = xrange(self.start, self.stop, self.step)
def __iter__(self):
return iter(self.xrange)
def __getitem__(self, item):
if type(item) is int:
if item < 0:
item += len(self)
return self.xrange[item]
if type(item) is slice:
# get the indexes, and then convert to the number
start, stop, step = item.start, item.stop, item.step
start = start if start != None else 0 # convert start = None to start = 0
if start < 0:
start += start
start = self[start]
if start < 0: raise IndexError(item)
step = (self.step if self.step != None else 1) * (step if step != None else 1)
stop = stop if stop is not None else self.xrange[-1]
if stop < 0:
stop += stop
stop = self[stop]
stop = stop
if stop > self.stop:
raise IndexError
if start < self.start:
raise IndexError
return Xrange(start, stop, step)
def index(self, value):
error = ValueError('object.index({0}): {0} not in object'.format(value))
index = (value - self.start)/self.step
if index % 1 != 0:
raise error
index = int(index)
try:
self.xrange[index]
except (IndexError, TypeError):
raise error
return index
def __len__(self):
return len(self.xrange)
솔직히, 전체 문제는 어리석은 일이며 xrange는이 모든 것을 어쨌든해야한다고 생각합니다 ...
책에 나오는 좋은 예 : Practical Python By Magnus Lie Hetland
>>> zip(range(5), xrange(100000000))
[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
앞의 예제에서 xrange 대신 range를 사용하지 않는 것이 좋습니다. 처음 5 개의 숫자 만 필요하지만 range는 모든 숫자를 계산하므로 시간이 오래 걸릴 수 있습니다. xrange를 사용하면 필요한 숫자 만 계산하므로 문제가되지 않습니다.
예 @Brian의 답변을 읽었습니다. 파이썬 3에서 range ()는 생성기이며 xrange ()는 존재하지 않습니다.
다음과 같은 이유로 범위로 이동하십시오.
1) xrange는 최신 Python 버전에서 사라질 것입니다. 이를 통해 향후 호환성을 쉽게 얻을 수 있습니다.
2) 범위는 xrange와 관련된 효율성을 가져옵니다.
자, 여기의 모든 사람들은 xrange와 range의 장단점에 대해 다른 의견을 가지고 있습니다. 그것들은 대부분 정확하고, xrange는 이터레이터이며, 범위를 정하고 실제 목록을 만듭니다. 대부분의 경우, 둘 사이의 차이점을 실제로 느끼지 못할 것입니다. (xrange가 아닌 range로 map을 사용할 수 있지만 더 많은 메모리를 사용합니다.)
그러나 당신이 집회를 듣고 싶다고 생각하는 것은 선호되는 선택이 xrange입니다. Python 3의 범위는 반복자이므로 코드 변환 도구 2to3은 xrange의 모든 사용을 범위로 올바르게 변환하고 범위 사용에 대한 오류 또는 경고를 발생시킵니다. 나중에 코드를 쉽게 변환하려면 xrange 만 사용하고 목록을 원할 때 list (xrange)를 사용합니다. 나는 시카고에서 올해 PyCon (2008)에서 CPython 스프린트 동안 이것을 배웠다.
range()
:range(1, 10)
1에서 10까지의 숫자를 반환하고 전체 목록을 메모리에 담습니다.xrange()
:와range()
같지만 목록을 반환하는 대신 요청시 범위의 숫자를 생성하는 객체를 반환합니다. 루핑의 경우 이것은range()
메모리 보다 약간 빠르며 더 효율적입니다.xrange()
이터레이터와 같은 객체로 요청시 숫자를 생성합니다 (지연 평가).
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__
Out[3]: xrange([start,] stop[, step]) -> xrange object
range()
같은 일을 xrange()
파이썬 3에서 수행하는 데 사용 기간이없는 xrange()
존재는 파이썬 3에서 range()
같은 순서를 여러 번 반복하는 경우 실제로 일부 시나리오에서 더 빠르게 할 수 있습니다. xrange()
매번 정수 객체를 재구성해야하지만 range()
실제 정수 객체를 갖습니다.
하지만 xrange
빠르게보다 range
대부분의 경우, 성능 차이는 꽤 최소한이다. 아래의 작은 프로그램은 a range
와 a에 대한 반복을 비교 합니다 xrange
.
import timeit
# Try various list sizes.
for list_len in [1, 10, 100, 1000, 10000, 100000, 1000000]:
# Time doing a range and an xrange.
rtime = timeit.timeit('a=0;\nfor n in range(%d): a += n'%list_len, number=1000)
xrtime = timeit.timeit('a=0;\nfor n in xrange(%d): a += n'%list_len, number=1000)
# Print the result
print "Loop list of len %d: range=%.4f, xrange=%.4f"%(list_len, rtime, xrtime)
아래 결과 xrange
는 실제로 더 빠르지 만 땀을 흘릴만큼 충분하지 않음을 보여줍니다 .
Loop list of len 1: range=0.0003, xrange=0.0003
Loop list of len 10: range=0.0013, xrange=0.0011
Loop list of len 100: range=0.0068, xrange=0.0034
Loop list of len 1000: range=0.0609, xrange=0.0438
Loop list of len 10000: range=0.5527, xrange=0.5266
Loop list of len 100000: range=10.1666, xrange=7.8481
Loop list of len 1000000: range=168.3425, xrange=155.8719
따라서 반드시 use을 사용 xrange
하지만 제한된 하드웨어를 사용하지 않는 한 너무 걱정하지 마십시오.
참고 URL : https://stackoverflow.com/questions/135041/should-you-always-favor-xrange-over-range
'Programing' 카테고리의 다른 글
PHP의 NOW () 함수 (0) | 2020.02.16 |
---|---|
일단 조각의 인스턴스 상태를 백 스택에 올바르게 저장하는 방법은 무엇입니까? (0) | 2020.02.16 |
VS2012에서 파일 미리보기 비활성화 (0) | 2020.02.16 |
MVC-3-converted-to-4 앱에 대한 System.Web.Optimization에 대한 참조를 추가하는 방법 (0) | 2020.02.16 |
제어의 반전 대 의존성 주입 (0) | 2020.02.16 |