Why does substring slicing with index out of range work?
Почему работает нарезка подстроки с индексом вне диапазона?
Почему это не 'example'[999:9999] приводит к ошибке? Поскольку 'example'[9] работает, какова мотивация этого?
Исходя из этого поведения, я могу предположить, что 'example'[3] это, по сути / внутренне, не то же самое, что 'example'[3:4], хотя оба результата дают одну и ту же 'm' строку.
Переведено автоматически
Ответ 1
Вы правы! 'example'[3:4] и 'example'[3] принципиально отличаются друг от друга, и нарезка за пределами последовательности (по крайней мере, для встроенных модулей) не вызывает ошибки.
Поначалу это может показаться удивительным, но если подумать, в этом есть смысл. Индексирование возвращает один элемент, а срезание возвращает подпоследовательность элементов. Итак, когда вы пытаетесь проиндексировать несуществующее значение, возвращать нечего. Но когда вы срезаете последовательность за пределами границ, вы все равно можете вернуть пустую последовательность.
Отчасти здесь сбивает с толку то, что строки ведут себя немного иначе, чем списки. Посмотрите, что происходит, когда вы проделываете то же самое со списком:
Здесь разница очевидна. В случае строк результаты кажутся идентичными, потому что в Python нет такого понятия, как отдельный символ вне строки. Одиночный символ - это всего лишь 1-символьная строка.
(Точную семантику нарезки вне диапазона последовательности см. в Ответе mgilson.)
Ответ 2
Ради добавления ответа, указывающего на надежный раздел в документации:
Учитывая выражение среза, подобное s[i:j:k],
Срез s от i до j с шагом k определяется как последовательность элементов с индексом x = i + n*k такая, что 0 <= n < (j-i)/k. Другими словами, индексы являются i, i+k, i+2*k, i+3*k и так далее, останавливаясь при достижении j (но никогда не включая j). Когда k положительное значение, i и j уменьшаются до len(s), если они больше
если вы пишете s[999:9999], python возвращает s[len(s):len(s)] since len(s) < 999, и ваш шаг положительный (1 - значение по умолчанию).
Ответ 3
Встроенные типы не проверяют границы нарезки. И хотя оба ваших примера, похоже, дают одинаковый результат, они работают по-разному; попробуйте вместо этого использовать список.