[python] range (start, end)에 end가 포함되지 않는 이유는 무엇입니까?

>>> range(1,11)

당신을 제공합니다

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

왜 1-11이 아닙니까?

그들은 무작위로 그렇게하기로 결정 했습니까? 아니면 내가 볼 수없는 가치가 있습니까?



답변

10 개의 요소를 포함하는를 range(0, 10)반환 [0,1,2,3,4,5,6,7,8,9]하는 것이 더 일반적이기 때문에 len(range(0, 10)). 프로그래머는 0 기반 인덱싱을 선호합니다.

또한 다음 공통 코드 스 니펫을 고려하십시오.

for i in range(len(li)):
    pass

range()정확히 올라 갔다 면 len(li)이것이 문제가 될 것입니까? 프로그래머는 명시 적으로 이것은 또한 선호하는 프로그래머의 일반적인 경향은 다음과 1. 뺄 필요 for(int i = 0; i < 10; i++)이상을 for(int i = 0; i <= 9; i++).

시작이 1 인 호출 범위를 자주 호출하는 경우 고유 한 기능을 정의 할 수 있습니다.

>>> def range1(start, end):
...     return range(start, end+1)
...
>>> range1(1, 10)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


답변

여기에는 유용한 알고리즘 설명이 있지만이 방법이 왜 작동하는지에 대한 간단한 ‘실제 생활’추론을 추가하는 데 도움이 될 수 있다고 생각합니다.

‘range (1,10)’과 같은 매개 변수 쌍이 “시작 및 끝”을 나타내는 것으로 생각하면 혼동 될 수 있습니다.

실제로 시작과 “중지”입니다.

이 경우 지금 있었다 다음 “끝”값을, 그래, 당신은 그 숫자가 순서의 마지막 항목으로 포함된다 기대할 수 있습니다. 그러나 “끝”이 아닙니다.

‘range (n)’만 사용한다면 물론 ‘n’번 반복하기 때문에 다른 사람들은 실수로이 매개 변수를 “count”라고 부릅니다. 이 논리는 시작 매개 변수를 추가 할 때 분류됩니다.

요점은 ” stop ” 이라는 이름을 기억하는 것 입니다. 즉, 도달하면 반복이 즉시 중지되는 지점입니다. 그 시점 이후 가 아닙니다 .

따라서 “시작”은 실제로 포함되는 첫 번째 값을 나타내지 만 “중지”값에 도달하면 중지하기 전에 ‘해당 값’을 계속 처리하지 않고 ‘파손’합니다.

아이들에게 이것을 설명 할 때 사용한 비유 중 하나는 아이러니하게도 아이들보다 더 잘 행동한다는 것입니다! 예정된 후에 멈추지 않습니다 -하고 있던 일을 끝내지 않고 즉시 멈 춥니 다. (그들은 이것을 얻는다;))

또 다른 비유-자동차를 운전할 때 정지 / 수율 / ‘주십시오’표시를 전달 하지 않고 자동차 옆 또는 뒤에 앉아있는 상태로 끝납니다. 기술적으로 당신은 당신이 멈출 때 여전히 그것에 도달하지 않았습니다. ‘여행에 통과 한 것들’에는 포함되어 있지 않습니다.

그 중 일부가 Pythonitos / Pythonitas에 설명하는 데 도움이되기를 바랍니다.


답변

독점 범위에는 몇 가지 이점이 있습니다.

한 가지 점은 각 항목 range(0,n)의 길이 목록에 대한 유효한 색인입니다 n.

또한 포함 범위가 아닌 range(0,n)의 길이 를가집니다.nn+1


답변

0부터 시작하는 인덱싱 및와 함께 잘 작동합니다 len(). 예를 들어, 목록에 10 개의 항목이 있으면 x0-9로 번호가 매겨집니다. range(len(x))0-9를 제공합니다.

물론, 사람들은 더 파이썬이 할의 당신을 말할 것이다 for item in xfor index, item in enumerate(x)보다는 for i in range(len(x)).

슬라이싱도 작동합니다 : foo[1:4]1-3의 항목입니다 foo(항목 1은 실제로 0부터 시작하는 인덱싱으로 인해 두 번째 항목입니다). 일관성을 유지하려면 둘 다 동일한 방식으로 작동해야합니다.

“원하는 첫 번째 숫자 다음에 원하지 않는 첫 번째 숫자 “라고 생각합니다. 1-10을 원하면 원하지 않는 첫 번째 숫자는 11 range(1, 11)입니다.

특정 응용 프로그램에서 번거로워지면 끝 색인에 1을 추가하고을 호출하는 작은 도우미 함수를 작성하는 것이 쉽습니다 range().


답변

범위 분할에도 유용합니다. range(a,b)로 분할 될 수 있습니다 range(a, x)range(x, b)포괄적 인 범위 당신이 중 하나를 작성합니다 반면, x-1또는 x+1. 범위를 분할 할 필요는 거의 없지만 목록을 자주 분할하는 경향이 있습니다. 이는 목록을 슬라이스 l[a:b]하면 a 번째 요소는 포함되지만 b 번째 요소는 포함하지 않는 이유 중 하나입니다 . 그런 다음 range동일한 속성을 가지면 일관성이 좋습니다.


답변

범위의 길이는 최고 값에서 최저값을 뺀 값입니다.

다음과 매우 유사합니다.

for (var i = 1; i < 11; i++) {
    //i goes from 1 to 10 in here
}

C 스타일 언어로.

루비의 범위와 마찬가지로 :

1...11 #this is a range from 1 to 10

그러나 Ruby는 여러 번 터미널 값을 포함시키려는 대안을 인식하고 대체 구문을 제공합니다.

1..10 #this is also a range from 1 to 10


답변

파이썬에서 기본적으로 시간을 range(n)반복합니다 n. 이것은 독점적 인 특성이므로 인쇄 할 때 마지막 값을주지 않는 이유입니다. 포괄적 인 값을 제공하는 함수를 만들 수 있습니다. 범위에서 언급 된 마지막 값도 인쇄합니다.

def main():
    for i in inclusive_range(25):
        print(i, sep=" ")


def inclusive_range(*args):
    numargs = len(args)
    if numargs == 0:
        raise TypeError("you need to write at least a value")
    elif numargs == 1:
        stop = args[0]
        start = 0
        step = 1
    elif numargs == 2:
        (start, stop) = args
        step = 1
    elif numargs == 3:
        (start, stop, step) = args
    else:
        raise TypeError("Inclusive range was expected at most 3 arguments,got {}".format(numargs))
    i = start
    while i <= stop:
        yield i
        i += step


if __name__ == "__main__":
    main()