Есть ли какой-либо более быстрый способ поменять два элемента списка в Python, чем
L[a], L[b] = L[b], L[a]
или мне пришлось бы прибегать к Cython или Weave или тому подобное?
Есть ли какой-либо более быстрый способ поменять два элемента списка в Python, чем
L[a], L[b] = L[b], L[a]
или мне пришлось бы прибегать к Cython или Weave или тому подобное?
Похоже, что компилятор 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
, и два сейва по сравнению с тремя нагрузками и тремя сейвами. Вы вряд ли найдете более быстрый механизм.
Если бы вы могли опубликовать образец репрезентативного кода, мы могли бы лучше выполнить бенчмаркинг ваших опций. 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())"
Я нашел этот метод как самый быстрый способ поменять два числа:
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)