11

I have for example the following list:

['|', u'MOM', u'DAD', '|', u'GRAND', '|', u'MOM', u'MAX', u'JULES', '|']

and want it to be split by the "|" so the result would look like:

[[u'MOM', u'DAD'],[ u'GRAND'], [u'MOM', u'MAX', u'JULES']]

How can I do this? I only find examples of sublists on the net which need a length of the elements

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
W0bble
  • 757
  • 1
  • 8
  • 24

4 Answers4

15
>>> [list(x[1]) for x in itertools.groupby(['|', u'MOM', u'DAD', '|', u'GRAND', '|', u'MOM', u'MAX', u'JULES', '|'], lambda x: x=='|') if not x[0]]
[[u'MOM', u'DAD'], [u'GRAND'], [u'MOM', u'MAX', u'JULES']]
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • This solution for me is full of magic but works perfect! Thank you – W0bble May 28 '11 at 21:07
  • 2
    Read the [groupby documentation](http://docs.python.org/library/itertools.html#itertools.groupby) for a start. :-) – Martijn Pieters May 28 '11 at 21:10
  • 1
    The full line is, for clarity: `[list(x[1]) for x in itertools.groupby(myList, lambda x: x=='|') if not x[0]]` – ninjagecko May 28 '11 at 22:04
  • @ninjagecko: That's why I split out the `list` and the `lambda` in [my answer](http://stackoverflow.com/questions/6164313/make-python-sublists-from-a-list-using-a-seperator/6164385#6164385). – johnsyweb May 28 '11 at 22:42
10

itertools.groupby() does this very nicely...

>>> import itertools
>>> l = ['|', u'MOM', u'DAD', '|', u'GRAND', '|', u'MOM', u'MAX', u'JULES', '|']
>>> key = lambda sep: sep == '|'
>>> [list(group) for is_key, group in itertools.groupby(l, key) if not is_key]
[[u'MOM', u'DAD'], [u'GRAND'], [u'MOM', u'MAX', u'JULES']]
johnsyweb
  • 136,902
  • 23
  • 188
  • 247
1

Simple solution using plain old for-loop (was beaten to it for the groupby solution, which BTW is better!)

seq = ['|', u'MOM', u'DAD', '|', u'GRAND', '|', u'MOM', u'MAX', u'JULES', '|']

S=[]
tmp=[]

for i in seq:
    if i == '|':
        S.append(tmp)
        tmp = []
    else:
        tmp.append(i)

# Remove empty lists
while True:
    try:
        S.remove([])
    except ValueError:
        break

print S

Gives

[[u'MOM', u'DAD'], [u'GRAND'], [u'MOM', u'MAX', u'JULES']]
Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
0
>>> reduce(
        lambda acc,x: acc+[[]] if x=='|' else acc[:-1]+[acc[-1]+[x]], 
        myList,
        [[]]
    )
[[], ['MOM', 'DAD'], ['GRAND'], ['MOM', 'MAX', 'JULES'], []]

Of course you'd want to use itertools.groupby, though you may wish to note that my approach "correctly" puts empty lists on the ends. =)

ninjagecko
  • 88,546
  • 24
  • 137
  • 145
  • When you say "correctly", how does that match with the desired output from the question or the linked article? – johnsyweb May 28 '11 at 22:04
  • 1
    @Johnsyweb I am well aware. Nevertheless the semantics of the specification however are inelegant and should be equivalent to `[].split(token)`; the input should just leave off the `'|'` on the ends. – ninjagecko May 28 '11 at 22:05