在给定分隔符的情况下,生成字符串中子字符串长度列表的最快方法是什么?

时间:2012-07-23 00:01:12

标签: python

我有一个字符串,我需要生成一个在给定分隔符中终止的所有子字符串的长度列表。

例如: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)?

5 个答案:

答案 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)]