Efficient way to rotate a list in python

后端 未结 26 1179
一生所求
一生所求 2020-11-22 03:14

What is the most efficient way to rotate a list in python? Right now I have something like this:

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


        
相关标签:
26条回答
  • 2020-11-22 03:42

    I think you are looking for this:

    a.insert(0, x)
    
    0 讨论(0)
  • 2020-11-22 03:43

    For an immutable implementation, you could use something like this:

    def shift(seq, n):
        shifted_seq = []
        for i in range(len(seq)):
            shifted_seq.append(seq[(i-n) % len(seq)])
        return shifted_seq
    
    print shift([1, 2, 3, 4], 1)
    
    0 讨论(0)
  • 2020-11-22 03:43

    If efficiency is your goal, (cycles? memory?) you may be better off looking at the array module: http://docs.python.org/library/array.html

    Arrays do not have the overhead of lists.

    As far as pure lists go though, what you have is about as good as you can hope to do.

    0 讨论(0)
  • 2020-11-22 03:43

    I don't know if this is 'efficient', but it also works:

    x = [1,2,3,4]
    x.insert(0,x.pop())
    

    EDIT: Hello again, I just found a big problem with this solution! Consider the following code:

    class MyClass():
        def __init__(self):
            self.classlist = []
    
        def shift_classlist(self): # right-shift-operation
            self.classlist.insert(0, self.classlist.pop())
    
    if __name__ == '__main__':
        otherlist = [1,2,3]
        x = MyClass()
    
        # this is where kind of a magic link is created...
        x.classlist = otherlist
    
        for ii in xrange(2): # just to do it 2 times
            print '\n\n\nbefore shift:'
            print '     x.classlist =', x.classlist
            print '     otherlist =', otherlist
            x.shift_classlist() 
            print 'after shift:'
            print '     x.classlist =', x.classlist
            print '     otherlist =', otherlist, '<-- SHOULD NOT HAVE BIN CHANGED!'
    

    The shift_classlist() method executes the same code as my x.insert(0,x.pop())-solution, otherlist is a list indipendent from the class. After passing the content of otherlist to the MyClass.classlist list, calling the shift_classlist() also changes the otherlist list:

    CONSOLE OUTPUT:

    before shift:
         x.classlist = [1, 2, 3]
         otherlist = [1, 2, 3]
    after shift:
         x.classlist = [3, 1, 2]
         otherlist = [3, 1, 2] <-- SHOULD NOT HAVE BIN CHANGED!
    
    
    
    before shift:
         x.classlist = [3, 1, 2]
         otherlist = [3, 1, 2]
    after shift:
         x.classlist = [2, 3, 1]
         otherlist = [2, 3, 1] <-- SHOULD NOT HAVE BIN CHANGED!
    

    I use Python 2.7. I don't know if thats a bug, but I think it's more likely that I missunderstood something here.

    Does anyone of you know why this happens?

    0 讨论(0)
  • 2020-11-22 03:43

    for similar functionality as shift in other languages:

    def shift(l):
        x = l[0]
        del(l[0])
        return x
    
    0 讨论(0)
  • 2020-11-22 03:44

    Possibly a ringbuffer is more suitable. It is not a list, although it is likely that it can behave enough like a list for your purposes.

    The problem is that the efficiency of a shift on a list is O(n), which becomes significant for large enough lists.

    Shifting in a ringbuffer is simply updating the head location which is O(1)

    0 讨论(0)
提交回复
热议问题