11

私は次のように文字列を処理しています:"125A12C15" 文字と数字の境界で文字列を分割する必要があります。たとえば、これは["125","A","12","C","15"].

位置ごとに調べて、それが文字か数字かを確認し、それに応じて連結するよりも、Pythonでこれを行うためのよりエレガントな方法はありますか? たとえば、この種の組み込み関数またはモジュールはありますか?

ご指摘ありがとうございます。

4

1 に答える 1

32

メソッドitertools.groupbyと一緒に使用します。str.isalpha

ドキュメントストリング:

groupby(iterable[, keyfunc]) -> key(value) の各値でグループ化された (key, sub-iterator) を返すイテレータを作成します。


ドキュメントストリング:

S.isalpha() -> ブール

S のすべての文字がアルファベットであり、S に少なくとも 1 文字ある場合は True を返し、そうでない場合は False を返します。


In [1]: from itertools import groupby

In [2]: s = "125A12C15"

In [3]: [''.join(g) for _, g in groupby(s, str.isalpha)]
Out[3]: ['125', 'A', '12', 'C', '15']

またはre.findall正規表現モジュールre.splitから:

In [4]: import re

In [5]: re.findall('\d+|\D+', s)
Out[5]: ['125', 'A', '12', 'C', '15']

In [6]: re.split('(\d+)', s)  # note that you may have to filter out the empty
                              # strings at the start/end if using re.split
Out[6]: ['', '125', 'A', '12', 'C', '15', '']

In [7]: re.split('(\D+)', s)
Out[7]: ['125', 'A', '12', 'C', '15']

パフォーマンスに関しては、正規表現を使用する方がおそらく高速であるようです。

In [8]: %timeit re.findall('\d+|\D+', s*1000)
100 loops, best of 3: 2.15 ms per loop

In [9]: %timeit [''.join(g) for _, g in groupby(s*1000, str.isalpha)]
100 loops, best of 3: 8.5 ms per loop

In [10]: %timeit re.split('(\d+)', s*1000)
1000 loops, best of 3: 1.43 ms per loop
于 2013-03-22T14:12:22.110 に答える