[python] 파이썬에서 목록을 회전시키는 효율적인 방법

파이썬에서 목록을 회전시키는 가장 효율적인 방법은 무엇입니까? 지금 나는 이와 같은 것을 가지고있다 :

>>> def rotate(l, n):
...     return l[n:] + l[:n]
... 
>>> l = [1,2,3,4]
>>> rotate(l,1)
[2, 3, 4, 1]
>>> rotate(l,2)
[3, 4, 1, 2]
>>> rotate(l,0)
[1, 2, 3, 4]
>>> rotate(l,-1)
[4, 1, 2, 3]

더 좋은 방법이 있습니까?



답변

A collections.deque는 양쪽 끝을 당기고 밀도록 최적화되어 있습니다. 그들은 심지어 전용 rotate()방법이 있습니다.

from collections import deque
items = deque([1, 2])
items.append(3)        # deque == [1, 2, 3]
items.rotate(1)        # The deque is now: [3, 1, 2]
items.rotate(-1)       # Returns deque to original state: [1, 2, 3]
item = items.popleft() # deque == [2, 3]


답변

그냥 사용하는 것은 pop(0)어떻습니까?

list.pop([i])

목록에서 지정된 위치에있는 항목을 제거하고 반환하십시오. 인덱스를 지정하지 않으면 a.pop()목록의 마지막 항목을 제거하고 반환합니다. ( i메소드 서명에서 괄호 안의 대괄호 는 매개 변수가 선택적이며 해당 위치에 대괄호를 입력하지 않아야 함을 나타냅니다.이 표기법은 Python Library Reference에서 자주 볼 수 있습니다.)


답변

Numpy는 다음 roll명령을 사용하여이를 수행 할 수 있습니다 .

>>> import numpy
>>> a=numpy.arange(1,10) #Generate some data
>>> numpy.roll(a,1)
array([9, 1, 2, 3, 4, 5, 6, 7, 8])
>>> numpy.roll(a,-1)
array([2, 3, 4, 5, 6, 7, 8, 9, 1])
>>> numpy.roll(a,5)
array([5, 6, 7, 8, 9, 1, 2, 3, 4])
>>> numpy.roll(a,9)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])


답변

이 작업을 수행 할 때 수행하려는 작업에 따라 다릅니다.

>>> shift([1,2,3], 14)

다음을 변경하고 싶을 수도 있습니다.

def shift(seq, n):
    return seq[n:]+seq[:n]

에:

def shift(seq, n):
    n = n % len(seq)
    return seq[n:] + seq[:n]


답변

내가 생각할 수있는 가장 간단한 방법 :

a.append(a.pop(0))


답변

별도의 데이터 구조를 구성하는 대신 이러한 요소 집합을 반복하려면 반복자를 사용하여 생성기 표현식을 구성하십시오.

def shift(l,n):
    return itertools.islice(itertools.cycle(l),n,n+len(l))

>>> list(shift([1,2,3],1))
[2, 3, 1]


답변

또한 목록을 제자리로 이동 (변경)하거나 함수가 새 목록을 반환하도록할지 여부에 따라 다릅니다. 내 테스트에 따르면 다음과 같은 것이 두 가지 목록을 추가하는 구현보다 20 배 이상 빠르기 때문입니다.

def shiftInPlace(l, n):
    n = n % len(l)
    head = l[:n]
    l[:n] = []
    l.extend(head)
    return l

실제로, l = l[:]전달 된 목록의 사본을 조작하기 위해 맨 위에 a 를 추가해도 여전히 두 배 빠릅니다.

http://gist.github.com/288272 에서 일부 타이밍을 사용한 다양한 구현