¡Estás en lo correcto! 'example'[3:4]
y 'example'[3]
son fundamentalmente diferentes, y cortar fuera de los límites de una secuencia (al menos para elementos integrados) no causa un error.
Puede resultar sorprendente al principio, pero tiene sentido cuando se piensa en ello. La indexación devuelve un solo elemento, pero la división devuelve una subsecuencia de elementos. Entonces, cuando intentas indexar un valor inexistente, no hay nada que devolver. Pero cuando corta una secuencia fuera de los límites, aún puede devolver una secuencia vacía.
Parte de lo que es confuso aquí es que las cadenas se comportan un poco diferente a las listas. Mira lo que pasa cuando haces lo mismo con una lista:
>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]
Aquí la diferencia es obvia. En el caso de las cadenas, los resultados parecen ser idénticos porque en Python, no existe un carácter individual fuera de una cadena. Un solo carácter es solo una cadena de 1 carácter.
(Para conocer la semántica exacta de cortar fuera del rango de una secuencia, consulte la respuesta de mgilson ).
[999:9999]
no es un índice, es un segmento y tiene una semántica diferente. De la introducción de Python: "Los índices de sectores degenerados se manejan con elegancia: un índice que es demasiado grande se reemplaza por el tamaño de la cadena, un límite superior más pequeño que el límite inferior devuelve una cadena vacía".