Why does range(start, end) not include end? [duplicate]
Почему range (начало, конец) не включает end?
>>> range(1,11)
дает вам
[1,2,3,4,5,6,7,8,9,10]
Почему не 1-11?
Они просто решили сделать это случайным образом или у этого есть какое-то значение, которое я не вижу?
Переведено автоматически
Ответ 1
Потому что более распространенным является вызов, range(0, 10) который возвращает [0,1,2,3,4,5,6,7,8,9] который содержит 10 элементов, что равно len(range(0, 10)). Помните, что программисты предпочитают индексирование на основе 0.
Также рассмотрим следующий распространенный фрагмент кода:
for i inrange(len(li)): pass
Не могли бы вы заметить, что если бы range() дошло ровно до len(li) этого значения, это было бы проблематично? Программисту нужно было бы явно вычесть 1. Это также следует общей тенденции программистов, предпочитающих for(int i = 0; i < 10; i++) over for(int i = 0; i <= 9; i++).
Если вы часто вызываете range с началом, равным 1, возможно, вам захочется определить свою собственную функцию:
Хотя здесь есть несколько полезных алгоритмических объяснений, я думаю, это может помочь добавить несколько простых рассуждений из "реальной жизни" относительно того, почему это работает именно так, которые я нашел полезными при знакомстве с предметом молодых новичков:
С чем-то вроде 'range (1,10)' может возникнуть путаница из-за мысли, что пара параметров представляет "начало и конец".
На самом деле это start и "stop".
Теперь, если бы это было значением "end", то да, вы могли бы ожидать, что это число будет включено в качестве последней записи в последовательности. Но это не "end".
Другие ошибочно называют этот параметр "count", потому что если вы используете только 'range (n)', то он, конечно, повторяется 'n' раз. Эта логика ломается, когда вы добавляете параметр start .
Итак, ключевым моментом является запоминание его названия: "stop". Это означает, что это точка, при достижении которой итерация немедленно прекращается. Не после этой точки.
Итак, хотя "start" действительно представляет первое включаемое значение, при достижении значения "stop" оно "прерывается" вместо того, чтобы продолжать обрабатывать "и это значение" перед остановкой.
Одна аналогия, которую я использовал, объясняя это детям, заключается в том, что, по иронии судьбы, он ведет себя лучше, чем дети! Он не останавливается после того, как должен был - он останавливается немедленно, не завершив то, что делал. (Они понимают это ;))
Другая аналогия - когда вы ведете машину, вы не проезжаете знак "стоп" / уступить дорогу" и в конечном итоге он оказывается где-то рядом с вашей машиной или позади нее. Технически вы все еще не достигли его, когда останавливаетесь. Это не включено в "то, что вы прошли в своем путешествии".
Я надеюсь, что кое-что из этого поможет объяснить Pythonitos /Pythonitas!
Ответ 3
Эксклюзивные диапазоны действительно имеют некоторые преимущества:
С одной стороны, каждый элемент в range(0,n) является допустимым индексом для списков длины n.
Также range(0,n) имеет длину n, а не n+1 которая была бы у инклюзивного диапазона.
Ответ 4
Это также полезно для разделения диапазонов; range(a,b) может быть разделен на range(a, x) и range(x, b), тогда как с включающим диапазоном вы бы написали либо x-1, либо x+1. Хотя вам редко нужно разделять диапазоны, вы склонны разделять списки довольно часто, что является одной из причин, по которой нарезка списка l[a:b] включает a-й элемент, но не b-й. Тогда range наличие одного и того же свойства делает его хорошо согласованным.