在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]

有没有更好的办法?


当前回答

如果效率是你的目标,(周期?内存?),您最好查看数组模块:http://docs.python.org/library/array.html

数组没有列表的开销。

就纯粹的列表而言,你所拥有的就是你所希望做的。

其他回答

另一个选择:

def move(arr, n):
    return [arr[(idx-n) % len(arr)] for idx,_ in enumerate(arr)]

如果效率是你的目标,(周期?内存?),您最好查看数组模块:http://docs.python.org/library/array.html

数组没有列表的开销。

就纯粹的列表而言,你所拥有的就是你所希望做的。

下面的方法是O(n)到位,辅助内存不变:

def rotate(arr, shift):
  pivot = shift % len(arr)
  dst = 0
  src = pivot
  while (dst != src):
    arr[dst], arr[src] = arr[src], arr[dst]
    dst += 1
    src += 1
    if src == len(arr):
      src = pivot
    elif dst == pivot:
      pivot = src

请注意,在python中,这种方法与其他方法相比效率非常低,因为它不能利用任何部分的本机实现。

用例是什么?通常,我们并不需要完全移位的数组——我们只需要访问移位数组中的少量元素。

获取Python切片是运行时O(k),其中k是切片,因此切片旋转是运行时n。deque旋转命令也是O(k)。我们能做得更好吗?

考虑一个非常大的数组(比方说,大到切片的计算速度很慢)。另一种解决方案是保留原始数组,并简单地计算在某种移位后存在于我们所期望的索引中的项的索引。

访问移位的元素就变成了O(1)。

def get_shifted_element(original_list, shift_to_left, index_in_shifted):
    # back calculate the original index by reversing the left shift
    idx_original = (index_in_shifted + shift_to_left) % len(original_list)
    return original_list[idx_original]

my_list = [1, 2, 3, 4, 5]

print get_shifted_element(my_list, 1, 2) ----> outputs 4

print get_shifted_element(my_list, -2, 3) -----> outputs 2 
def solution(A, K):
    if len(A) == 0:
        return A

    K = K % len(A)

    return A[-K:] + A[:-K]

# use case
A = [1, 2, 3, 4, 5, 6]
K = 3
print(solution(A, K))

例如,给定

A = [3, 8, 9, 7, 6]
K = 3

函数应该返回[9,7,6,3,8]。进行了三次轮换:

[3, 8, 9, 7, 6] -> [6, 3, 8, 9, 7]
[6, 3, 8, 9, 7] -> [7, 6, 3, 8, 9]
[7, 6, 3, 8, 9] -> [9, 7, 6, 3, 8]

再举一个例子

A = [0, 0, 0]
K = 1

函数应该返回[0,0,0]

鉴于

A = [1, 2, 3, 4]
K = 4

函数应该返回[1,2,3,4]