我有一个字符串,我需要生成一个在给定分隔符中终止的所有子字符串的长度列表。
例如:string ='a0ddb0gf0',separator ='0',所以我需要生成:lengths = [2,4,3],因为len('a0')== 2,len('ddb0' )= 4,len('gf0')== 3.
我知道可以通过以下方式完成(例如):
separators = [index for index in range(len(string)) if string[index]==separator]
lengths = [separators[index+1] - separators[index] for index in range(len(separators)-1)]
但我需要非常快速地完成(大量数据)。为大量数据生成中间列表非常耗时。
是否有一个解决方案能够整齐而快速地完成这项工作(py2.7)?
答案 0 :(得分:3)
最快?不知道。您可能想对其进行分析。
>>> print [len(s) for s in 'a0ddb0gf0'.split('0')]
[1, 3, 2, 0]
而且,如果你真的不想包含零长度字符串:
>>> print [len(s) for s in 'a0ddb0gf0'.split('0') if s]
[1, 3, 2]
答案 1 :(得分:2)
就个人而言,我喜欢itertools.groupby()
>>> from itertools import groupby
>>> sep = '0'
>>> data = 'a0ddb0gf0'
>>> [sum(1 for i in g) for (k, g) in groupby(data, sep.__ne__) if k]
[1, 3, 2]
根据每个元素是否等于分隔符对数据进行分组,然后获取元素不相等的每个组的长度(通过对组中的每个项目求和1)。
itertools函数通常非常快,但我不确定这比split()
好多少。我认为强烈支持的一点是,它可以无缝地处理多个连续出现的分隔符。它还将处理data
的任何迭代,而不仅仅是字符串。
答案 2 :(得分:1)
我不知道这会有多快,但这是另一种方式:
def len_pieces(s, sep):
i = 0
while True:
f = s.find(sep, i)
if f == -1:
yield len(s) - i
return
yield f - i + 1
i = f + 1
答案 3 :(得分:0)
>>> [len(i) for i in re.findall('.+?0', 'a0ddb0gf0')]
[2, 4, 3]
您可以使用re.finditer
来避免中间列表,但性能可能没有太大差异:
[len(i.group(0)) for i in re.finditer('.+?0', 'a0ddb0gf0')]
答案 4 :(得分:0)
也许使用re:
[len(m.group()) for m in re.finditer('(.*?)0', s)]