2013-03-14 4 views
1

range()xrange()의 차이점을 잘 알고 있습니다. 마지막 한 후, 다음으로 높은 값을 반환 xrange 객체의 정지 값입니다 볼 수있는, 그러나Python 2의 이상한 xrange() 동작

>>> for item in xrange(1,10,4): 
...  print item 
... 
1 
5 
9 
>>> 

:

>>> xrange(1,10,2) 
xrange(1, 11, 2) 

>>> xrange(1,10,4) 
xrange(1, 13, 4) 

기능적으로,이 올바른지 : 나는 xrange()에 뭔가 이상한 발견 법적 가치. 이유가 뭐야? 이제 파이썬이 동작합니다에 xrange 파이썬 3에서와 동일한 기능을 제공

range() 예상대로 :

>>> range(1,10,4) 
range(1, 10, 4) 
>>> range(1,10,2) 
range(1, 10, 2) 
>>> 
+2

아니오 'xrange()는'범위() '과 동일하지'파이썬 3에서 후자는 새로운 유형. 최종 값은'range()'또는'xrange()'에 포함되지 않습니다. 'step' 값 때문에'11'이나'10'도 범위 출력에 포함되지 않습니다. –

+0

@MartijnPieters 나는 의견의 전반부에 동의합니다. 내 질문을 수정했습니다. –

+0

@MartijnPieters 지금은 결코 포함되지 않은 정지 값과 관련하여 예, 알고 있습니다. xrange 객체가 마지막 합법적 인 값 + 정지 값으로 정지 값과 함께 반환되는 이유는 무엇입니까? –

답변

2

xrange(1, 10, 4)xrange(1, 13, 4)과 같습니다. 파이썬 2

>>> for item in xrange(1,13,4): 
...  print item 
... 
1 
5 
9 
>>> 

xrangestart, stop, step 인수를 정규화하고 : 귀하의 예제를 사용합니다. 내부적으로 xrange 구현은 start, step 및 stop 대신에 트리플 시작, step 및 length (xrange 객체의 요소 수)를 저장합니다. 여기서 [1] 구현 방법 xrange.__repr__()이다

rtn = PyString_FromFormat("xrange(%ld, %ld, %ld)", 
          r->start, 
          r->start + r->len * r->step, 
          r->step); 

[1] https://github.com/replit/empythoned/blob/master/cpython/Objects/rangeobject.c

+0

좋아요. CPython 소스에 대한 링크를 공유해 주셔서 감사합니다. –

+0

내 질문이 정확히 무엇인지 알기 때문에 나는 대답을 받아들입니다. –

+0

이것은 공식 CPython 3.3 소스에 대한 링크입니다. http://hg.python.org/cpython/file/e45db319e590/Objects/rangeobject.c#l808 –

3

range 또는 xrange a의 정지 값은 항상 배타적입니다. docs (파이썬 2)로부터

견적 : step 양수

경우, 마지막 요소stop보다 큰 start + i * step이하이고; step이 음수이면 마지막 요소는 start + i * step보다 작고stop보다 작습니다.

그리고 Python 3위한

: 양성 step 들어

는 범위 (R)의 내용은 화학식 r[i] = start + step*ii >= 0r[i] < stop에 의해 결정된다. 음극 용 step

이 범위의 내용은 여전히 ​​r[i] = start + step*i 식에 의해 결정되지만, 제약 및 i >= 0r[i] > stop
이다. xrangerepr()에 관한 질문의 두 번째 부분에 대해

: 기본 파이썬 개체에 대한

xrange(1, 10, 4)xrange(1, 13, 4)가 동일하고 repr()은 일반적으로 개체를 다시하려면 유효한 파이썬 코드를 반환합니다. 이것은 처음에 객체를 생성 한 파이썬 코드와 정확히 같을 필요는 없습니다.

+1

예, 답안의 후반부가 내가 찾고 있던 답변이므로 동의 할 것입니다. 감사. –

+0

죄송합니다. @ zodiac의 대답을 받아 들였기 때문에 정확한 답을 얻을 수있는 소스 코드를 지적하기까지했습니다. –

2

정말 중요한가요?

효과은 동일합니다. 10 또는 11 중 하나도 xrange()의 출력에 포함되지 않으며 xrange(1, 11, 2)등가에서 xrange(1, 10, 2)입니다.

파이썬 2 범위 형식 (xrange()의 결과)은 최종 값이 아닌 범위 길이를 저장하므로 repr 출력을 만들기 위해 최종 값이 계산됩니다. 그리고 계단 값을 사용했기 때문에 계산 결과는 start + length * step 수식으로 표시됩니다. 구현을 위해 길이가 더 중요한 값이므로 end 값은 안전하게 삭제하고 필요에 따라 다시 계산할 수 있습니다.

당신이 xrange(1, 10, 2)을 만들 때, 그것은 범위의 길이를 저장 을 계산

대신 최종 값의 : 길이뿐만 아니라에

if (step > 0 && lo < hi) 
return 1UL + (hi - 1UL - lo)/step; 
else if (step < 0 && lo > hi) 
return 1UL + (lo - 1UL - hi)/(0UL - step); 
else 
return 0UL; 

파이썬 3 Range 개체를 저장 종료 값 따라서 개체를 쿼리하여 repr 출력에 표시 할 수 있습니다.

+0

나는 왜 당신이 "정말로 중요합니까?"라고 묻는 이유를 확신하지 못합니다. 나는 효과가 동일하다는 것을 알고있다. 그건 내가 요구 한 것이 아니다. 어쨌든. –