Подтвердить что ты не робот

Самый быстрый способ поменять элементы в списке Python

Есть ли какой-либо более быстрый способ поменять два элемента списка в Python, чем

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

или мне пришлось бы прибегать к Cython или Weave или тому подобное?

4b9b3361

Ответ 1

Похоже, что компилятор Python оптимизирует временный кортеж с помощью этой конструкции:

код:

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)

выход:

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        

Две нагрузки, ROT_TWO, и два сейва по сравнению с тремя нагрузками и тремя сейвами. Вы вряд ли найдете более быстрый механизм.

Ответ 2

Если бы вы могли опубликовать образец репрезентативного кода, мы могли бы лучше выполнить бенчмаркинг ваших опций. FWIW, для следующего безумного теста, я получаю ускорение в 3 раза с Shed Skin и 10-кратное ускорение с 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())"

Ответ 3

Я нашел этот метод как самый быстрый способ поменять два числа:

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)