Обтекание списка python как операция среза - PullRequest
14 голосов
/ 25 декабря 2010

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

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

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

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

Есть ли способ обернуть вышеупомянутый массив, перейдя клевый

[1, 2, 0]

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

Ответы [ 4 ]

17 голосов
/ 25 декабря 2010

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

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

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

2 голосов
/ 25 декабря 2010

Слева:

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

Справа:

L[-1:], L[:-1] = L[:1], L[1:]
1 голос
/ 25 декабря 2010

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

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

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

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

0 голосов
/ 13 мая 2019

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

Например, например:

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]

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

...