在python中,什么更有效?修改列表或字符串?

Chr*_*ris 1 python string list

无论易用性如何,计算效率更高?不断切片列表并附加到它们?或者采取子串并做同样的事情?

举个例子,假设我有两个二进制字符串"11011"和"01001".如果我将这些表示为列表,我将选择一个随机的"切片"点.假设我得到3.我将获取第一个字符串的前3个字符和第二个字符串的剩余字符(所以我必须将它们切片)并从中创建一个新字符串.

通过切割子串或将其表示为列表([1,1,0,1,1])而不是字符串,可以更有效地完成这项工作吗?

Sil*_*ost 7

>>> a = "11011"
>>> b = "01001"
>>> import timeit
>>> def strslice():
    return a[:3] + b[3:]

>>> def lstslice():
    return list(a)[:3] + list(b)[3:]
>>> c = list(a)
>>> d = list(b)
>>> def lsts():
    return c[:3] + d[3:]

>>> timeit.timeit(strslice)
0.5103488475836432
>>> timeit.timeit(lstslice)
2.4350100538824613
>>> timeit.timeit(lsts)
1.0648406858527295
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 5

timeit是一个很好的微基准测试工具,但是当您想要比较的操作可能涉及就地更改时,需要非常小心地使用它 - 在这种情况下,您需要包含旨在制作所需副本的额外操作.然后,第一次只是"额外"开销:

$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b)'
100000 loops, best of 3: 5.01 usec per loop
$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b)'
100000 loops, best of 3: 5.06 usec per loop
Run Code Online (Sandbox Code Playgroud)

因此,制作我们需要的两个全新列表(避免更改)需要花费超过5微秒(当关注小差异时,运行至少2-3次以观察不确定性范围).之后:

$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b);x=a[:3]+b[3:]'
100000 loops, best of 3: 5.5 usec per loop
$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b);x=a[:3]+b[3:]'
100000 loops, best of 3: 5.47 usec per loop
Run Code Online (Sandbox Code Playgroud)

在这种情况下,字符串切片和连接可以看到另外花费410-490纳秒.和:

$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b);la[3:]=lb[3:]'
100000 loops, best of 3: 5.99 usec per loop
$ python -mtimeit -s'a="11011";b="01001"' 'la=list(a);lb=list(b);la[3:]=lb[3:]'
100000 loops, best of 3: 5.99 usec per loop
Run Code Online (Sandbox Code Playgroud)

可以看到就地列表拼接成本为930-980纳秒.差异安全地高于噪声/不确定性水平,因此您可以可靠地声明,对于此用例,使用字符串将花费大约一半的时间与使用列表就地工作.当然,测量一系列与您典型的瓶颈任务相关且具有代表性的用例也是至关重要的!