Почему somelist[len(somelist)] генерирует ошибку IndexError, а не somelist[len(somelist):]?

Я понимаю, что somelist[len(somelist)] не может получить доступ к индексу, который находится за пределами определенного списка - это имеет смысл.

Но почему тогда Python позволяет вам делать somelist[len(somelist):]?

Я даже читал, что somelist[len(somelist):] = [1] эквивалентно somelist.append(1)

Но почему нотация среза меняет тот факт, что индекс «len(somelist)» все еще находится за пределами диапазона списка?


person Alex Krycek    schedule 18.03.2013    source источник


Ответы (3)


Вот что-то из документация. Существуют определенные правила нарезки любого итерируемого объекта; Особо следует отметить № 4, выделение мое:

Срез s от i до j определяется как последовательность элементов с индексом k, такая что i <= k < j. Если i или j больше len(s), используйте len(s). Если i опущено или None, используйте 0. Если j опущено или None, используйте len(s). Если i больше или равно j, фрагмент пуст.

person Makoto    schedule 18.03.2013
comment
Хорошо, это объясняет, почему возвращается пустой список (как указывали другие). Но почему somelist[len(somelist):] = [1] позволяет вам добавлять 1 к некоторому списку? Разве эквивалент предыдущей команды не просто [] = [1]? Прошу прощения, не пытаюсь быть тупым. - person Alex Krycek; 18.03.2013
comment
Если i ›= j, срез пустой (в данный момент в нем нет элементов), но он не является пустым объектом списка; это все еще фрагмент, начинающийся с i, и назначение ему списка удаляет его текущие элементы (их нет) из списка и вставляет элементы в назначенный список в позицию i. - person rakslice; 18.10.2013
comment
Например, предположим, что я установил x = range(5), а затем назначил фрагмент x[3:2] = [8,7,6], x теперь будет [0, 1, 2, 8, 7, 6, 3, 4]. Это та же самая ситуация; в назначении слайсов в случае i = len(s) нет ничего особенного. - person rakslice; 18.10.2013

В индексе len(somelist) ничего нет (индексы списка начинаются с 0 в python). Поэтому попытка доступа к несуществующему элементу вызывает ошибку.

Однако нарезка списка (с синтаксисом myList[i:]) возвращает новый список, содержащий элементы, включая и после i. Поскольку в списке нет элементов по индексу i (или после), возвращается пустой список

person inspectorG4dget    schedule 18.03.2013
comment
@AlexKrycek: Да. Назначение среза — это не то же самое, что просто чтение среза. - person BrenBarn; 18.03.2013

Из документации Python:

Вырожденные индексы срезов обрабатываются изящно: слишком большой индекс заменяется размером строки, верхняя граница меньше нижней возвращает пустую строку.

Таким образом, индекс > размер списка автоматически корректируется, и somelist[len(somelist):] возвращает элементы после последнего, т.е. нада.

person dda    schedule 18.03.2013