Ответ 1
Вы правы! 'example'[3:4]
и 'example'[3]
принципиально различаются, и вырезание за пределами последовательности (по крайней мере, для встроенных модулей) не вызывает ошибку.
Сначала это может быть удивительно, но имеет смысл, когда вы думаете об этом. Индексирование возвращает один элемент, а нарезка возвращает подпоследовательность элементов. Поэтому, когда вы пытаетесь проиндексировать несуществующее значение, возвращать нечего. Но когда вы нарезаете последовательность за пределами границ, вы все равно можете вернуть пустую последовательность.
Часть того, что сбивает с толку, заключается в том, что строки ведут себя немного иначе, чем списки. Посмотрите, что происходит, когда вы делаете то же самое со списком:
>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]
Здесь разница очевидна. В случае строк результаты кажутся идентичными, потому что в Python нет такой вещи, как отдельный символ вне строки. Один символ - это просто строка из 1 символа.
(Точную семантику среза вне диапазона последовательности см. В ответе mgilson.)