了解元组列表转换行为:list(t)还是[*t]哪个更好?

kaz*_*aza 0 python

我有一个元组如下:

t=(1,2,3,4,5,6)
Run Code Online (Sandbox Code Playgroud)

我想把它转换成一个列表,虽然有一个直接的方式

l=list(t)
Run Code Online (Sandbox Code Playgroud)

我想知道下面的效率是否更低,如果是这样的话?

l=[*t]
Run Code Online (Sandbox Code Playgroud)

这更像是要理解解压缩并将其打包回列表中是否有任何开销list(tuple).

我会尝试对两者进行基准测试并在此处发布结果,但如果有人能够提出一些见解,那就太棒了.

skr*_*sme 5

使用timeitdis模块可以很容易地检查自己.我把这个剧本拼凑在了一起:

import timeit
import dis

def func(t):
    return list(t)

def unpack(t):
    return [*t]

def func_wrapper():

    t = (1,2,3,4,5,6)
    func(t)

def unpack_wrapper():

    t = (1,2,3,4,5,6)
    unpack(t)

print("Disassembly with function:")
print(dis.dis(func))

print("Dissassembly with unpack:")
print(dis.dis(unpack))

print("Func time:")
print(timeit.timeit(func_wrapper, number=10000))
print("Unpack time:")
print(timeit.timeit(unpack_wrapper, number=10000))
Run Code Online (Sandbox Code Playgroud)

并运行它显示此输出:

Disassembly with function:                       
  5           0 LOAD_GLOBAL              0 (list)
              2 LOAD_FAST                0 (t)   
              4 CALL_FUNCTION            1       
              6 RETURN_VALUE                     
None                                             
Dissassembly with unpack:                        
  8           0 LOAD_FAST                0 (t)   
              2 BUILD_LIST_UNPACK        1       
              4 RETURN_VALUE                     
None                                             
Func time:                                       
0.002832347317420137                             
Unpack time:                                       
0.0016913349487029865
Run Code Online (Sandbox Code Playgroud)

反汇编表明函数方法的反汇编需要通过解包方法进行一次额外的函数调用.时序结果表明,正如预期的那样,函数调用与使用内置运算符的开销会导致执行时间的显着增加.

仅通过执行时间,解包就更"有效".但请记住,执行时间只是等式的一部分 - 这必须与可读性和某些情况下的内存消耗(更难以进行基准测试)相平衡.在大多数情况下,我建议您坚持使用该功能,因为它更容易阅读.如果频繁执行此代码(如在长时间运行的循环中)并且位于脚本的关键路径上,我只会切换到解包方法.