Почему не 'example'[999:9999]
приводит к ошибке? Поскольку 'example'[9]
это так, какова мотивация этого?
Исходя из этого поведения, я могу предположить, что 'example'[3]
это по существу / внутренне не то же самое, что и 'example'[3:4]
, хотя оба результата приводят к одной и той же 'm'
строке.
[999:9999]
не индекс, это срез и имеет другую семантику. Из вступления к python: «Вырожденные индексы срезов обрабатываются изящно: слишком большой индекс заменяется размером строки, верхняя граница меньше нижней возвращает пустую строку».Ответы:
Вы правы!
'example'[3:4]
и'example'[3]
принципиально отличаются, и нарезка за пределы последовательности (по крайней мере, для встроенных модулей) не вызывает ошибки.Поначалу это может показаться удивительным, но, если подумать, это имеет смысл. Индексирование возвращает один элемент, а разрезание возвращает подпоследовательность элементов. Поэтому, когда вы пытаетесь проиндексировать несуществующее значение, возвращать нечего. Но когда вы нарезаете последовательность за пределами границ, вы все равно можете вернуть пустую последовательность.
Отчасти сбивает с толку то, что строки ведут себя немного иначе, чем списки. Посмотрите, что происходит, когда вы делаете то же самое со списком:
>>> [0, 1, 2, 3, 4, 5][3] 3 >>> [0, 1, 2, 3, 4, 5][3:4] [3]
Здесь разница очевидна. В случае строк результаты кажутся идентичными, потому что в Python нет такой вещи, как отдельный символ вне строки. Одиночный символ - это просто строка из 1 символа.
(Точную семантику нарезки вне диапазона последовательности см. В ответе Мильсона .)
источник
None
вместо ошибки - это обычное соглашение Python, когда вам нечего возвращать.None
в этом случае будет сложнее отличить индекс вне границ отNone
значения внутри списка. Но даже если бы для этого существовал обходной путь, мне остается ясно, что возвращение пустой последовательности - это то, что нужно делать, когда дан фрагмент, выходящий за границы. Это аналогично объединению двух непересекающихся множеств.None
ценностях в списке.Ради добавления ответа, указывающего на надежный раздел в документации :
Учитывая такое выражение среза, как
s[i:j:k]
,если вы пишете
s[999:9999]
, питон возвращается ,s[len(s):len(s)]
такlen(s) < 999
и ваш шаг положителен (1
- по умолчанию).источник
k
положительный,i
и когда ониj
также увеличиваются,-len(s)
когда они меньше? напримерs = 'bac'; s[-100:2] == s[-len(s):2]
k
положительно, Python будет масштабироватьсяi
иj
так , чтобы они соответствовали границе последовательности. В вашем примереs[-100:2] == s[0:2]
(== s[-len(s):2]
кстати). Аналогичноs[-100:100] == s[0:2]
.Нарезка не проверяется границами встроенными типами. И хотя оба ваших примера, кажется, дают одинаковый результат, они работают по-разному; вместо этого попробуйте их со списком.
источник