views:

101

answers:

3

I have strings that look like this example: "AAABBBCDEEEEBBBAA"

Any character is possible in the string.

I want to split it to a list like: ['AAA','BBB','C','D','EEEE','BBB','AA']

so every continuous stretch of the same characters goes to separate element of the split list.

I know that I can iterate over characters in the string, check every i and i-1 pair if they contain the same character, etc. but is there a more simple solution out there?

+12  A: 

We could use Regex:

>>> import re
>>> r = re.compile(r'(.)\1*')
>>> [m.group() for m in r.finditer('AAABBBCDEEEEBBBAA')]
['AAA', 'BBB', 'C', 'D', 'EEEE', 'BBB', 'AA']

Alternatively, we could use itertools.groupby.

>>> import itertools
>>> [''.join(g) for k, g in itertools.groupby('AAABBBCDEEEEBBBAA')]
['AAA', 'BBB', 'C', 'D', 'EEEE', 'BBB', 'AA']

timeit shows Regex is faster (for this particular string) (Python 2.6, Python 3.1). But Regex is after all specialized for string, and groupby is a generic function, so this is not so unexpected.

KennyTM
Wow, thanks, regex solution is cool, groupby too, how is it possible that I spend so much time on this problem before sending the question to stackoverflow and getting the answer in 5 minutes ;-)
jan
+1 for using regexp to solve a problem that regexp is for :)
Kimvais
+2  A: 
import itertools
s = "AAABBBCDEEEEBBBAA"
["".join(chars) for _, chars in itertools.groupby(s)]
Glenn Maynard
+2  A: 
>>> from itertools import groupby
>>> [''.join(g) for k, g in groupby('AAAABBBCCD')]
['AAAA', 'BBB', 'CC', 'D']

And by normal string manipulation

>>> a=[];S="";p=""
>>> s
'AAABBBCDEEEEBBBAA'
>>> for c in s:
...     if c != p: a.append(S);S=""
...     S=S+c
...     p=c
...
>>> a.append(S)
>>> a
['', 'AAA', 'BBB', 'C', 'D', 'EEEE', 'BBB', 'AA']
>>> filter(None,a)
['AAA', 'BBB', 'C', 'D', 'EEEE', 'BBB', 'AA']
ghostdog74