Подтвердить что ты не робот

Обтекание списком python как операции среза

Рассмотрим следующий простой код python

>>> L = range(3)
>>> L
[0, 1, 2]

Мы можем взять срезы этого массива следующим образом:

>>> L[1:3]
[1, 2]

Есть ли способ обернуть вокруг указанного массива, сдвинув его влево

[1, 2, 0]

просто используя операции среза?

4b9b3361

Ответ 1

Поверните левые элементы n (или справа для отрицательного n):

L = L[n:] + L[:n]

Обратите внимание, что collections.deque поддерживает вращения, Возможно, лучше использовать это вместо списков.

Ответ 2

Слева:

L[:1], L[1:] = L[-1:], L[:-1]

Справа:

L[-1:], L[:-1] = L[:1], L[1:]

Ответ 3

На мой взгляд, нет способа, если вы не согласитесь разрезать и объединить списки, как показано выше. Чтобы сделать обертывание, которое вы описываете, вам нужно изменить индекс начала и окончания.

  • Положительный начальный индекс отсекает некоторые начальные позиции.
  • Отрицательный начальный индекс дает вам некоторые из элементов хвоста, снова разрезая начальные элементы.
  • Положительный финишный индекс отсекает некоторые элементы хвоста.
  • Индекс отрицательной отделки дает вам некоторые из начальных позиций, снова режущие элементы хвоста.

Никакая комбинация из них не может обеспечить точку обертывания, когда за хвостовыми элементами следуют начальные элементы. Таким образом, вся вещь не может быть создана.

Существуют многочисленные обходные пути. См. Ответы выше, см. Также itertools.islice и .chain для последовательного подхода без копирования, если последовательный доступ - это то, что вам нужно (например, в цикле).

Ответ 4

Если вы не слишком привязаны к точному синтаксису среза, вы можете написать функцию, которая выдает желаемый результат, включая поведение обтекания.

Например, вот так:

def wrapping_slice(lst, *args):
    return [lst[i%len(lst)] for i in range(*args)]

Пример вывода:

>>> L = range(3)
>>> wrapping_slice(L, 1, 4)
[1, 2, 0]
>>> wrapping_slice(L, -1, 4)
[2, 0, 1, 2, 0]
>>> wrapping_slice(L, -1, 4, 2)
[2, 1, 0]

Предостережение: Вы не можете использовать это в левой части назначения среза.