Как реверсирование строки работает со строкой [:: -1] - PullRequest
0 голосов
/ 28 февраля 2020

Я понимаю, что синтаксис секционирования содержит 3 аргумента, а именно:

  1. start

  2. stop

  3. шаг

Со следующими значениями по умолчанию:

  1. start = 0

  2. stop = длина строки

  3. шаг = 1

Итак, для

> string = "abc"

> string[::]

вернется

> "abc"

Но для

> string[::-1]

не должно ли оно вернуться:

> "a"

Так как, string [start = 0] = 'a' Тогда, string [start + step], то есть string [0-1] = 'c', но потому что это не меньше, чем остановка = 3, он сломается.

ИЛИ я думаю в неправильном направлении, а python просто разрезает строку в обычном направлении и возвращает обратную эту строку, если шаг отрицательные? Чтобы упростить, как отрицательный шаг работает внутри?

Ответы [ 2 ]

2 голосов
/ 28 февраля 2020

Если указано отрицательное значение шага, Python меняет начальное и конечное значения. Кроме того, если значения начала и конца не указаны, по умолчанию они задают начало и конец последовательности.

При условии s[i:j:k], следующая цитата из раздела операций с общей последовательностью из применяется документация по встроенным типам:

Если i или j опущены или отсутствуют, они становятся «конечными» значениями (конец которых зависит от знака k).


Что касается того, как это работает под капотом, в CPython есть две функции для обработки подписок на списки, list_subscript() (для чтения) и list_ass_subscript() (для назначения).

В обеих этих функциях, после проверки того, что нижний индекс определяет срез, выполняются вызовы PySlice_Unpack() и PySlice_AdjustIndices() для извлечения и нормализации начальных и конечных значений.

Обработка начальных значений

С PySlice_Unpack():

if (r->start == Py_None) {
    *start = *step < 0 ? PY_SSIZE_T_MAX : 0;

Если начальное значение None, а значение шага отрицательное, начальное значение установлено на максимально возможное значение .

Затем в PySlice_AdjustIndices():

else if (*start >= length) {
    *start = (step < 0) ? length - 1 : length;

Если начальное значение больше, чем длина списка (что, несомненно, связано с назначением выше) и значение шага является отрицательным, тогда начальное значение устанавливается на length - 1 (т. е. length относится к длине последовательности).

Остановка обработки значения

С PySlice_Unpack():

if (r->stop == Py_None) {
    *stop = *step < 0 ? PY_SSIZE_T_MIN : PY_SSIZE_T_MAX;

Если значение останова равно None, а значение шага отрицательно, значение останова устанавливается на наименьшее возможное значение.

Затем в PySlice_AdjustIndices():

if (*stop < 0) {
    *stop = (step < 0) ? -1 : 0;

Если значение остановки отрицательное (что связано с приведенным выше назначением), а значение шага отрицательное, значение остановки устанавливается до -1.

Таким образом, при вводе string[::-1] вы получите:

  • Начальное значение: len (строка) - 1
  • Стоп-значение : -1
  • Шаг: -1
1 голос
/ 28 февраля 2020

Когда в качестве step передается отрицательное значение, значения по умолчанию для start и stop обратные. start изменяется от «начала последовательности» до «конца последовательности», а stop изменяется от «конца последовательности» до «начала последовательности». Если этого не сделать, у вас возникнут проблемы с выполнением полного среза, поскольку конец любого среза является исключительным; mystr[len(mystr)-1:0:-1] исключит первый символ (потому что 0 не будет включен), и вы не можете вместо *1003* передать go одно прошлое 0, потому что это будет означать то же самое, что и len(mystr)-1 (благодаря тому, как Python обрабатывает отрицательные индексы), и вы вообще ничего не отрежете. Переключение значений по умолчанию, так что пропуск конца (или, что то же самое, явное прохождение None) выполняется до самого начала, включительно, является единственным разумным решением.

...