Fastest way to swap elements in Python list

后端 未结 3 1621
北海茫月
北海茫月 2020-11-29 21:27

Is there any any faster way to swap two list elements in Python than

L[a], L[b] = L[b], L[a]

or would I have to resort to Cython or Weave o

相关标签:
3条回答
  • 2020-11-29 21:38

    If you could post a representative code sample, we could do a better job of benchmarking your options. FWIW, for the following dumb benchmark, I get about a 3x speedup with Shed Skin and a 10x speedup with PyPy.

    from time import time
    
    def swap(L):
        for i in xrange(1000000):
            for b, a in enumerate(L):
                L[a], L[b] = L[b], L[a]
    
    def main():
        start = time()
        L = list(reversed(range(100)))
        swap(L[:])
        print time() - start
        return L
    
    if __name__ == "__main__":
        print len(main())
    
    # for shedskin:
    # shedskin -b -r -e listswap.py && make
    # python -c "import listswap; print len(listswap.main())"
    
    0 讨论(0)
  • 2020-11-29 21:40

    Looks like the Python compiler optimizes out the temporary tuple with this construct:

    code:

    import dis
    
    def swap1():
      a=5
      b=4
      a, b = b, a
    
    def swap2():
      a=5
      b=4
      c = a
      a = b
      b = c
    
    print 'swap1():'
    dis.dis(swap1)
    print 'swap2():'
    dis.dis(swap2)
    

    output:

    swap1():
      6           0 LOAD_CONST               1 (5)
                  3 STORE_FAST               0 (a)
    
      7           6 LOAD_CONST               2 (4)
                  9 STORE_FAST               1 (b)
    
      8          12 LOAD_FAST                1 (b)
                 15 LOAD_FAST                0 (a)
                 18 ROT_TWO             
                 19 STORE_FAST               0 (a)
                 22 STORE_FAST               1 (b)
                 25 LOAD_CONST               0 (None)
                 28 RETURN_VALUE        
    swap2():
     11           0 LOAD_CONST               1 (5)
                  3 STORE_FAST               0 (a)
    
     12           6 LOAD_CONST               2 (4)
                  9 STORE_FAST               1 (b)
    
     13          12 LOAD_FAST                0 (a)
                 15 STORE_FAST               2 (c)
    
     14          18 LOAD_FAST                1 (b)
                 21 STORE_FAST               0 (a)
    
     15          24 LOAD_FAST                2 (c)
                 27 STORE_FAST               1 (b)
                 30 LOAD_CONST               0 (None)
                 33 RETURN_VALUE        
    

    Two loads, a ROT_TWO, and two saves, versus three loads and three saves. You are unlikely to find a faster mechanism.

    0 讨论(0)
  • 2020-11-29 21:44

    I found this method as the fastest way to swap two numbers:

    mylist   = [11,23,5,8,13,17];
    first_el = mylist.pop(0)
    last_el  = mylist.pop(-1)
    mylist.insert(0, last_el)  
    mylist.append(first_el)
    
    0 讨论(0)
提交回复
热议问题