无论易用性如何,计算效率更高?不断切片列表并附加到它们?或者采取子串并做同样的事情?
举个例子,假设我有两个二进制字符串“11011”和“01001”。如果我将这些表示为列表,我将选择一个随机的“切片”点。让我说我得到3.我将获取第一个字符串的前3个字符和第二个字符串的剩余字符(所以我必须将它们切片)并从中创建一个新字符串。
通过切割子串或将其表示为列表([1,1,0,1,1])而不是字符串,可以更有效地完成这项工作吗?
答案 0 :(得分: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
答案 1 :(得分: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
因此,制作我们需要的两个全新列表(避免更改)需要花费超过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
在这种情况下,字符串切片和连接可以看作另外花费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
就地列表拼接可以看作花费930-980纳秒。差异安全地高于噪声/不确定性水平,因此您可以可靠地声明,对于此用例,使用字符串将花费大约一半的时间与使用列表就地工作。当然,衡量一系列与您典型的瓶颈任务相关的用例也很重要!
答案 2 :(得分:4)
通常,修改列表比修改字符串更有效,因为字符串是不可变的。
答案 3 :(得分:0)
这实际上取决于实际用例,正如其他人所说,对其进行概要分析,但一般来说,附加到列表会更好,因为它可以在适当的位置完成,而“追加到字符串”实际上会创建一个新的字符串连接旧字符串。这可以迅速消耗记忆力。 (实际上,这与计算效率不同)。
编辑:如果您希望使用二进制值计算效率,请不要使用字符串或列表。使用整数和按位运算。使用最新版本的python,您可以在需要时使用二进制表示:
>>> bin(42)
'0b101010'
>>> 0b101010
42
>>> int('101010')
101010
>>> int('101010', 2)
42
>>> int('0b101010')
...
ValueError: invalid literal for int() with base 10: '0b101010'
>>> int('0b101010', 2)
42
编辑2:
def strslice(a, b):
return a[:3] + b[3:]
可能更好地写成:
def binspice(a, b):
mask = 0b11100
return (a & mask) + (b & ~mask)
>>> a = 0b11011
>>> b = 0b1001
>>> bin(binsplice(a, b))
'0b11001
>>>
如果二进制数不同,可能需要修改。