Почему срезы подстроки с индексом вне диапазона работают? - PullRequest
60 голосов
/ 29 февраля 2012

Почему 'example'[999:9999] не приводит к ошибке?Поскольку 'example'[9] знает, что за этим стоит?

Из этого поведения я могу предположить, что 'example'[3], по сути / внутренне, не совпадает с 'example'[3:4], даже если оба результата приводят к одному и тому же результату.'m' строка.

Ответы [ 3 ]

48 голосов
/ 29 февраля 2012

Ты прав!'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 .)

19 голосов
/ 08 марта 2017

Ради добавления ответа, указывающего на надежный раздел в документации :

С учетом выражения среза, например 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). <strong>Когда k положительно, i и j уменьшаются до len (s), если они больше

если вы пишете s[999:9999], python возвращает s[len(s):len(s)], начиная с len(s) < 999, и ваш шаг положительный (1 - по умолчанию).

5 голосов
/ 29 февраля 2012

Срезы не проверяются границами встроенными типами. И хотя оба ваших примера имеют одинаковый результат, они работают по-разному; попробуйте их со списком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...