Ответ 1
Часть вопроса о показателях вне диапазона
Логика среза автоматически обрезает индексы по длине последовательности.
Разрешение индексов срезов расширяться за конечные точки было сделано для удобства. Было бы больно иметь диапазон проверки каждого выражения, а затем корректировать пределы вручную, поэтому Python сделает это за вас.
Рассмотрим вариант использования желания отображать не более первых 50 символов текстового сообщения.
Самый простой способ (что сейчас делает Python):
preview = msg[:50]
Или трудный путь (проверяйте лимит самостоятельно):
n = len(msg)
preview = msg[:50] if n > 50 else msg
Вручную реализовать эту логику для настройки конечных точек было бы легко забыть, было бы легко ошибиться (обновление 50 в двух местах), было бы многословно и было бы медленно. Python перемещает эту логику во внутренности, где она лаконична, автоматическая, быстрая и правильная. Это одна из причин, по которой я люблю Python :-)
Часть вопроса относительно несоответствия длины назначений длине ввода
ОП также хотел знать обоснование для разрешения назначений, таких как p[20:100] = [7,8]
где цель назначения имеет другую длину (80), чем длина замещающих данных (2).
Легче всего увидеть мотивацию по аналогии со строками. Рассмотрим "five little monkeys".replace("little", "humongous")
. Обратите внимание, что у цели "маленький" есть только шесть букв, а у "огромных" - девять. Мы можем сделать то же самое со списками:
>>> s = list("five little monkeys")
>>> i = s.index('l')
>>> n = len('little')
>>> s[i : i+n ] = list("humongous")
>>> ''.join(s)
'five humongous monkeys'
Это все сводится к удобству.
До появления методов copy() и clear() это были популярные выражения:
s[:] = [] # clear a list
t = u[:] # copy a list
Даже сейчас мы используем это для обновления списков при фильтрации:
s[:] = [x for x in s if not math.isnan(x)] # filter-out NaN values
Надеюсь, что эти практические примеры дают хорошее представление о том, почему нарезка работает так, как она работает.