tags:

views:

205

answers:

6

In python, how can I split a long list into a list of lists wherever I come across '-'. For example, how can I convert:

['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']

to

[['1', 'a', 'b'],['2','c','d'],['3','123','e'],['4']]

Many thanks in advance.

+4  A: 
import itertools

l = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']
r = []

i = iter(l)
while True:
  a = [x for x in itertools.takewhile(lambda x: x != '---', i)]
  if not a:
    break
  r.append(a)
print r

# [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']]
Ignacio Vazquez-Abrams
+1 I like this better then my similar solution (will delete it shortly) because of the efficient `iter` approach (only consume it once). But you probably mean to replace `for j in range(7)` with `while True` to handle arbitrary lengths.
ChristopheD
@ChristopheD: Yes, fixed.
Ignacio Vazquez-Abrams
+13  A: 
In [17]: import itertools
# putter around 22 times
In [39]: l=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']

In [40]: [list(g) for k,g in itertools.groupby(l,'---'.__ne__) if k]
Out[40]: [['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']]
unutbu
+1 Nice (didn't immediately think of `itertools.groupby` here but it fits the bill indeed)
ChristopheD
Thank you for your answer. Is there a way to check x=='---' in the above line with a regular expression (something like x==re.match('-'))? Many thanks
DGT
Yes, you could use something like `[list(g) for k,g in itertools.groupby(l,lambda x: re.match('---',x)) if not k]`. The expression `re.match(...)` returns None when `x` does not match the pattern. Thus `k` is `None` for the elements you want to keep. So I changed the condition to `if not k`.
unutbu
great! thanks a lot.
DGT
You can use `'---'.__ne__` instead of the lambda function
gnibbler
@gnibbler: Oh, that's slick!
unutbu
A: 

It's been a while since I've done any python so my syntax is going to be way off, but a simple loop should suffice.

Keep track of the indexes in two numbers

firstList = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']
listIndex = 0
itemIndex = 0
ii = 0
foreach item in firstList
  if(firstList[ii] == '---') 
    listIndex = listIndex + 1
    itemIndex = 0
    ii = ii + 1
  else secondList[listIndex][itemIndex] = firstList[ii]
mphair
A: 
import itertools

a = ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']
b = [list(x[1]) for x in itertools.groupby(a, '---'.__eq__) if not x[0]]

print b     # or print(b) in Python 3

Result is

[['1', 'a', 'b'], ['2', 'c', 'd'], ['3', '123', 'e'], ['4']]
JAB
A: 

Here's a solution without itertools:

def foo(input):
    output = []
    currentGroup = []
    for value in input:
        if '-' in value:  #if we should break on this element 
            currentGroup.append( value )
        elif currentGroup:
            output.append( currentGroup )
            currentGroup = []
    if currentGroup:
        output.append(currentGroup) #appends the rest if not followed by separator    
    return output

print ( foo ( ['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4'] ) )
CrazyJugglerDrummer
Beyond a certain threshold, readability is relative. That just looks like a big mass of code to me.
Ignacio Vazquez-Abrams
@Crazy: Using (1) `value.find('-') == -1` instead of `'-' in value` (2) camelCase (2) redundant parentheses in `(el)if` sometimes (3) extraneous spaces inside parentheses sometimes (4) statement long enough to make SO insert the ferschlugginer horizontal scroll bar (5) no space after comma sometimes makes it look like a big mess of fugly code to me.
John Machin
You're both right. Edited code and description. :)
CrazyJugglerDrummer
A: 

Here's one way to do it:

lst=['1', 'a', 'b','---', '2','c','d','---','3','123','e','---','4']
indices=[-1]+[i for i,x in enumerate(lst) if x=='---']+[len(lst)]
answer=[lst[indices[i-1]+1:indices[i]] for i in xrange(1,len(indices))]
print answer

Basically, this finds the locations of the string '---' in the list and then slices the list accordingly.

MAK