>>> range(1,11)
дает тебе
[1,2,3,4,5,6,7,8,9,10]
Почему не 1-11?
Они просто решили сделать это наугад или это имеет какую-то ценность, которую я не вижу?
>>> range(1,11)
дает тебе
[1,2,3,4,5,6,7,8,9,10]
Почему не 1-11?
Они просто решили сделать это наугад или это имеет какую-то ценность, которую я не вижу?
Потому что чаще всего вызывается range(0, 10)
, который возвращает [0,1,2,3,4,5,6,7,8,9]
, который содержит 10 элементов, что равно 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(start, count)
?
- person Mark Ransom; 22.12.2010
range(10)
эквивалентно range(0, 10)
.
- person moinudin; 22.12.2010
range1
не будет работать с диапазонами, размер шага которых отличается от 1
.
- person dimo414; 21.05.2015
range(0, 10, 2)
это [0, 2, 4, 6, 8]
, который, очевидно, не имеет 10 элементов. Полагаю, в нем было бы end / step
элемента, конечно, с округлением в меньшую сторону.
- person dub stylee; 26.10.2016
range1 = lambda start,end,step: range(start,end+1,step) for i in range(1,26): print(i) for i in range1(1,25,3): print(i)
- person Doogle; 12.03.2017
for i in range(len(li)):
скорее антипаттерн. Следует использовать enumerate
.
- person hans; 06.03.2018
Хотя здесь есть некоторые полезные алгоритмические объяснения, я думаю, что это может помочь добавить несколько простых аргументов из реальной жизни относительно того, почему это работает таким образом, что я нашел полезным при ознакомлении с этим предметом молодых новичков:
С чем-то вроде 'range (1,10)' может возникнуть путаница, если подумать, что пара параметров представляет собой «начало и конец».
Это собственно старт и «стоп».
Теперь, если бы оно было конечным значением, то да, можно было бы ожидать, что это число будет включено в качестве последней записи в последовательности. Но это еще не «конец».
Другие ошибочно называют этот параметр «count», потому что, если вы когда-либо используете только «range (n)», то он, конечно же, повторяет «n» раз. Эта логика нарушается, когда вы добавляете параметр запуска.
Поэтому важно помнить его название: «стоп». Это означает, что это точка, при достижении которой итерация немедленно останавливается. Не после этого момента.
Таким образом, хотя «start» действительно представляет собой первое значение, которое нужно включить, при достижении значения «stop» оно «прерывается», а не продолжает обрабатывать «это также» перед остановкой.
Одна аналогия, которую я использовал, объясняя это детям, заключается в том, что, по иронии судьбы, они лучше себя ведут, чем дети! Он не останавливается после того, как должен был - он останавливается немедленно, не завершая того, что он делал. (Они это понимают;))
Еще одна аналогия: когда вы ведете машину, вы не проезжаете знак "стоп / выход / уступите дорогу" и в итоге видите, что он сидит где-то рядом или сзади, Ваш автомобиль. Технически вы все еще не достигли этого, когда останавливаетесь. Это не входит в «вещи, которые вы передали в своем путешествии».
Я надеюсь, что кое-что из этого поможет в объяснении Pythonitos / Pythonitas!
Эксклюзивные линейки имеют некоторые преимущества:
Во-первых, каждый элемент в range(0,n)
является допустимым индексом для списков длины n
.
Также range(0,n)
имеет длину n
, а не n+1
, как в инклюзивном диапазоне.
Он хорошо работает в сочетании с индексированием с нуля и len()
. Например, если у вас есть 10 элементов в списке x
, они пронумерованы от 0 до 9. range(len(x))
дает вам 0-9.
Конечно, люди скажут вам, что Pythonic больше выполняет for item in x
или for index, item in enumerate(x)
, чем for i in range(len(x))
.
Так же работает и нарезка: foo[1:4]
- это элементы 1-3 из foo
(учитывая, что элемент 1 на самом деле является вторым элементом из-за индексации с нуля). Для единообразия оба они должны работать одинаково.
Я думаю об этом так: «первое число, которое вам нужно, за которым следует первое число, которое не нужно». Если вы хотите от 1 до 10, первое число, которое вам не нужно, будет 11, так что это range(1, 11)
.
Если это становится громоздким в конкретном приложении, достаточно просто написать небольшую вспомогательную функцию, которая добавляет 1 к конечному индексу и вызывает range()
.
w = 'abc'; w[:] == w[0:len(w)]; w[:-1] == w[0:len(w)-1];
- person kevpie; 22.12.2010
Это также полезно для разделения диапазонов; 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
Рассмотрим код
for i in range(10):
print "You'll see this 10 times", i
Идея состоит в том, что вы получаете список длиной y-x
, который вы можете (как вы видите выше) перебирать.
Ознакомьтесь с документами по Python для диапазона - они считают итерацию цикла основным вариант использования.
В основном в python 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()
Во многих случаях просто удобнее рассуждать.
В принципе, мы могли бы думать о диапазоне как о интервале между start
и end
. Если start <= end
, длина интервала между ними равна end - start
. Если бы len
был фактически определен как длина, у вас было бы:
len(range(start, end)) == start - end
Однако мы считаем целые числа, входящие в диапазон, вместо того, чтобы измерять длину интервала. Чтобы указанное выше свойство оставалось истинным, мы должны включить одну из конечных точек и исключить другую.
Добавление параметра step
похоже на введение единицы длины. В этом случае вы ожидаете
len(range(start, end, step)) == (start - end) / step
по длине. Чтобы получить счет, вы просто используете целочисленное деление.
range(n)
в Python возвращает значение от 0 до n-1. Соответственно, range(1,n)
от 1 до n-1. Итак, если вы хотите опустить первое значение и получить также последнее значение (n), вы можете сделать это очень просто, используя следующий код.
for i in range(1, n + 1):
print(i) #prints from 1 to n
range()
имеет смысл гораздо чаще. - person John La Rooy   schedule 22.12.2010a < i <= b
- единственное, для которогоa
иb
никогда не должны покидать набор натуральных чисел, пока диапазонi
либо пуст, либо находится внутри набора натуральных чисел. Хотя это в основном косметический аргумент, я думаю, что он вполне обоснован. - person andreasdr   schedule 21.04.2015range
не имеет никакого смысла. - person EugZol   schedule 02.02.2021