Как объяснить обратную последовательность последовательности с помощью нотации среза a [:: - 1]
Из учебник python.org
Индексы фрагментов имеют полезные значения по умолчанию; опускаемый первый индекс по умолчанию равен нулю, опускаемый второй индекс по умолчанию соответствует размеру нарезанной строки.
>>> a = "hello"
>>> print(a[::-1])
olleh
Как говорится в учебнике, a[::-1]
должен равняться a[0:5:-1]
но a[0:5:-1]
пуст следующим образом:
>>> print(len(a[0:5:-1]))
0
Вопрос не является дубликатом explain-slice-notation. Этот вопрос касается общего использования среза в python.
Ответы
Ответ 1
Я думаю, что документы, возможно, немного вводят в заблуждение, но необязательные аргументы разрезания, если они опущены, такие же, как с использованием None
:
>>> a = "hello"
>>> a[::-1]
'olleh'
>>> a[None:None:-1]
'olleh'
Вы можете видеть, что эти 2 вышеуказанных фрагмента идентичны байт-коду CPython:
>>> import dis
>>> dis.dis('a[::-1]') # or dis.dis('a[None:None:-1]')
1 0 LOAD_NAME 0 (a)
3 LOAD_CONST 0 (None)
6 LOAD_CONST 0 (None)
9 LOAD_CONST 2 (-1)
12 BUILD_SLICE 3
15 BINARY_SUBSCR
16 RETURN_VALUE
Для отрицательного step
замещенные значения для None
равны len(a) - 1
для start
и -len(a) - 1
для end
:
>>> a[len(a)-1:-len(a)-1:-1]
'olleh'
>>> a[4:-6:-1]
'olleh'
>>> a[-1:-6:-1]
'olleh'
Это может помочь вам визуализировать его:
h e l l o
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
Ответ 2
Все, что он делает, это slice. Вы выбираете. start stop и step, так что в основном вы говорите, что он должен начинаться в начале и в начале, но идти назад (-1).
Если вы сделаете это с -2, оно пропустит буквы:
>>> a[::-2]
'olh'
Когда вы делаете [0:5:-1]
, вы начинаете с первой буквы и возвращаетесь прямо на 5, и, таким образом, она останавливается. только если вы попробуете [-1::-1]
, он правильно сможет перейти к началу, выполнив шаги с отрицательным 1.
Изменить ответ на комментарии
Как указано в документации, говорится
пропущенный второй индекс по умолчанию равен размеру строки: кружочки.
Предположим, что мы имеем str
с len(str) = 5
. Когда вы разрезаете строку и опускаете, оставьте, второе число по умолчанию соответствует длине строки, нарезанной, в этом случае - 5.
i str[1:] == str[1:5]
, str[2:] == str[2:5]
. Предложение относится к длине исходного объекта, а не к недавно нарезаемому объекту.
Кроме того, этот ответ отличный
Ответ 3
Вы путаетесь с поведением степпинга. Чтобы получить тот же результат, вы можете сделать следующее:
a[0:5][::-1]
'olleh'
В самом деле, stepping хочет "обвести" вокруг себя в вашем случае, но вы ограничиваете его перемещением, вызывая a[0:5:-1]
.
Ответ 4
a[0:5:-1]
не имеет большого смысла, так как при использовании этих обозначений индексы означают: a[start:end:step]
. Когда вы используете отрицательный шаг, ваше конечное значение должно быть в "более ранней" позиции, чем ваше начальное значение.
Ответ 5
Вы заметите, что третий аргумент среза step
не указан в части приведенного вами урока. Этот конкретный фрагмент принимает позитивный шаг.
Когда вы добавляете возможность отрицательного шага, поведение на самом деле довольно интуитивно. Пустой параметр start
относится к тому, какой конец последовательности будет начинаться, чтобы пройти через всю последовательность в направлении, указанном значением step
. Другими словами, это относится к наименьшему индексу (для подсчета), если у вас есть положительный шаг, и самый высокий индекс (для обратного отсчета), если у вас есть отрицательный шаг. Аналогично, пустой параметр end
относится к тому, какой конец последовательности будет завершен после того, как вы пройдете через соответствующее направление.