元组是否比Python中的列表更有效?
时间:2020-03-05 18:54:58 来源:igfitidea点击:
在元素的实例化和检索方面,元组和列表之间是否存在性能差异?
解决方案
回答
元组应该比列表稍有效率,因此比列表更快,因为它们是不可变的。
回答
通常,我们可能期望元组会稍微快一些。但是,我们一定要测试特定情况(如果差异可能会影响程序的性能,请记住"过早的优化是万恶之源")。
Python非常简单:timeit是朋友。
$ python -m timeit "x=(1,2,3,4,5,6,7,8)" 10000000 loops, best of 3: 0.0388 usec per loop $ python -m timeit "x=[1,2,3,4,5,6,7,8]" 1000000 loops, best of 3: 0.363 usec per loop
和...
$ python -m timeit -s "x=(1,2,3,4,5,6,7,8)" "y=x[3]" 10000000 loops, best of 3: 0.0938 usec per loop $ python -m timeit -s "x=[1,2,3,4,5,6,7,8]" "y=x[3]" 10000000 loops, best of 3: 0.0649 usec per loop
因此,在这种情况下,元组的实例化速度几乎快一个数量级,但列表的项目访问实际上要快一些!因此,如果要创建一些元组并多次访问它们,则实际上使用列表可能会更快。
当然,如果我们要更改一项,则列表肯定会更快,因为我们需要创建一个完整的新元组来更改一项(因为元组是不可变的)。
回答
dis模块反汇编一个函数的字节码,对于查看元组和列表之间的区别很有用。
在这种情况下,我们可以看到访问元素会生成相同的代码,但是分配元组要比分配列表快得多。
>>> def a(): ... x=[1,2,3,4,5] ... y=x[2] ... >>> def b(): ... x=(1,2,3,4,5) ... y=x[2] ... >>> import dis >>> dis.dis(a) 2 0 LOAD_CONST 1 (1) 3 LOAD_CONST 2 (2) 6 LOAD_CONST 3 (3) 9 LOAD_CONST 4 (4) 12 LOAD_CONST 5 (5) 15 BUILD_LIST 5 18 STORE_FAST 0 (x) 3 21 LOAD_FAST 0 (x) 24 LOAD_CONST 2 (2) 27 BINARY_SUBSCR 28 STORE_FAST 1 (y) 31 LOAD_CONST 0 (None) 34 RETURN_VALUE >>> dis.dis(b) 2 0 LOAD_CONST 6 ((1, 2, 3, 4, 5)) 3 STORE_FAST 0 (x) 3 6 LOAD_FAST 0 (x) 9 LOAD_CONST 2 (2) 12 BINARY_SUBSCR 13 STORE_FAST 1 (y) 16 LOAD_CONST 0 (None) 19 RETURN_VALUE
回答
元组是不可变的,具有更高的内存效率;为了提高效率,列表列出了整体内存,以允许没有常量realloc
的追加。因此,如果要遍历代码中恒定的值序列(例如,"向上","右侧","向下","左侧"的方向),则首选元组,因为此类元组是预-在编译时计算。
访问速度应该相同(它们都作为连续数组存储在内存中)。
但是,当我们处理可变数据时," alist.append(item)"比" atuple + =(item,)"更受青睐。请记住,元组应被视为没有字段名称的记录。
回答
如果列表或者元组中的所有项目都属于同一类型,则还应该考虑标准库中的"数组"模块。它可以更快并且占用更少的内存。