【问题标题】:Fastest way to swap elements in Python list在 Python 列表中交换元素的最快方法
【发布时间】:2011-06-01 01:07:51
【问题描述】:

有没有比在 Python 中交换两个列表元素更快的方法

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

还是我必须求助于CythonWeave 之类的?

【问题讨论】:

  • 不,不是在开玩笑。我正在实施一种算法,该算法已完成数十亿次(取决于问题的大小),并且想知道是否有什么简单的方法可以加快速度。
  • 在尝试加速这个特定的交换之前,可能有很多方法可以加速你的程序。一些上下文可能会很有趣。
  • 为我的硕士项目处理过类似的 TSP 本地搜索问题,我可以告诉你,你会 a) 想要选择比 2-Opt 等更好的算法,b) Psyco(或Cython 等)是你的朋友。
  • Gerald,如果你有兴趣,我想我仍然有一个简单的 Tkinter GUI,它可以读取 TSPLIB 问题并在解决问题时(通过 2-Opt)在单独的线程中显示它们。它有助于可视化您的算法是否正常运行。
  • @UkuLoskit:别傻了。

标签: python performance


【解决方案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,两次保存,而不是三次加载和三次保存。您不太可能找到更快的机制。

【讨论】:

  • 先生,您刚刚向我展示了我喜欢 python 的另一个原因。我从来不知道“dis”
  • 太棒了!感谢您让我们了解 dis
【解决方案2】:

如果您可以发布具有代表性的代码示例,我们可以更好地对您的选项进行基准测试。 FWIW,对于以下愚蠢的基准测试,Shed Skin 的速度提高了 3 倍,PyPy 的速度提高了 10 倍。

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())"

【讨论】:

  • 感谢您尝试蜕皮。当我尝试这个程序时,我看到了大约 100 倍的加速。你还记得你用的是哪个版本的蜕皮吗?
【解决方案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)

【讨论】:

    猜你喜欢
    • 2012-09-17
    • 2018-12-05
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 2021-11-10
    相关资源
    最近更新 更多