2012-02-26 49 views
62

可能重复:
Efficient way to shift a list in pythonPython列表旋转

我想用物品任意数量的旋转Python列表的右侧或左侧(后者使用负论据)。

事情是这样的:

>>> l = [1,2,3,4] 
>>> l.rotate(0) 
[1,2,3,4] 
>>> l.rotate(1) 
[4,1,2,3] 
>>> l.rotate(-1) 
[2,3,4,1] 
>>> l.rotate(4) 
[1,2,3,4] 

怎么可能这样做?

+2

我不使用Python,但如果你有push/pop方法,你可以使用l.push(l.pop())。然后循环它。这将涵盖前进。 – 2012-02-26 22:29:19

+0

[这个问题](http://stackoverflow.com/questions/2150108/efficient-way-to-shift-a-list-in-python)有帮助吗? – simchona 2012-02-26 22:30:18

+0

这个问题似乎相关:http://stackoverflow.com/questions/1212025/moving-values-in-a-list-in-python – 2012-02-26 22:30:36

回答

118
def rotate(l, n): 
    return l[-n:] + l[:-n] 

更多常规方向:

def rotate(l, n): 
    return l[n:] + l[:n] 

实施例:

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

rotate(example_list, 2) 
# [3, 4, 5, 1, 2] 

的参数rotate是一个列表和一个整数,表示的转变。该函数使用slicing创建两个新列表并返回这些列表的连接。 rotate函数不会修改输入列表。

+0

不错,简单。它旋转的方向与问题中指定的方向相反。 – 2012-02-26 22:36:40

+0

爱的优雅! – varunl 2012-02-26 22:41:05

+0

@DrewNoakes它确实是这样... – YXD 2012-02-26 22:47:31

82

如果适用,您可以使用collections.deque作为一种解决方案:

import collections 

d = collections.deque([1,2,3,4,5]) 
d.rotate(3) 

print d 
>>> deque([3, 4, 5, 1, 2]) 

作为奖励,我希望它会比内置列表更快。

+3

对于未来的读者:'collections.deque rotate()'比根据https://wiki.python.org/moin/TimeComplexity – Geoff 2016-12-16 17:35:04

+0

更快切片不应该提及集合默认情况下向左旋转? – 2017-07-24 03:17:24

+0

@HasanIqbalAnik deque.rotate向右旋转https://docs.python.org/3/library/collections.html#collections.deque.rotate – miles82 2017-12-10 20:05:27

14

下面的函数将旋转列表lx空间向右:

def rotate(l, x): 
    return l[-x:] + l[:-x] 

注意,如果x是范围[-len(l), len(l)]之外,这将只返回原始列表。为了使为x所有值正常工作,使用:

def rotate(li, x): 
    return li[-x % len(li):] + li[:-x % len(li)] 
+0

有没有办法这一点没有'return'?我试过'l = l [n:] + l [:n]'但是当我尝试返回'l'时,我得到原文。 – GinKin 2014-03-18 17:46:51

+0

@GinKin为什么没有回报?这就是你从一个函数返回的东西。我的意思是,你可以使用lambda,但这只是让隐含的返回。 – 2014-03-18 17:54:42

+0

我想“到位”,使其因此它不会返回任何东西,如果我输入'运行功能之后>>> l'我会得到一个旋转的列表,而不是原来的。 – GinKin 2014-03-18 17:59:19

4
>>> l=[1,2,3,4] 
>>> l[1:]+l[:1] 
[2, 3, 4, 1] 
>>> l=[1,2,3,4] 
>>> l[2:]+l[:2] 
[3, 4, 1, 2] 
>>> l[-1:]+l[:-1] 
[4, 1, 2, 3] 

一般旋转n向左或向右移动(负y)(在调用rotate正y),则:

def rotate(l, y=1): 
    if len(l) == 0: 
     return l 
    y = y % len(l) # Why? this works for negative y 

    return l[y:] + l[:y] 

如果你想旋转的方向与你的例子相同,只是否定y旋转。

def rotate(l, y=1): 
    if len(l) == 0: 
     return l 
    y = -y % len(l)  # flip rotation direction 

    return l[y:] + l[:y]