1

文字列があり、指定された区切り文字で終わるすべての部分文字列の長さのリストを生成する必要があります。

例: string = 'a0ddb0gf0'、separator = '0' なので、次を生成する必要があります: lengths = [2,4,3], since 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)?

4

5 に答える 5

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]
于 2012-07-23T00:03:57.560 に答える
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()。私が強く支持していると思う点の 1 つは、区切り文字の複数回の連続発生をシームレスに処理できることです。文字列だけでなく、反復可能なものも処理dataします。

于 2012-07-23T00:23:35.310 に答える
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
于 2012-07-23T00:10:55.297 に答える
0

多分 re: を使って

[len(m.group()) for m in re.finditer('(.*?)0', s)]
于 2012-07-23T00:10:34.367 に答える
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')]
于 2012-07-23T00:07:59.443 に答える