4

I have a list of objects, and I wish to get a list of list of objects, splitted using objects from another list, like that:

l = ['x',1,2,3,'a',5,6,1,7]

and another list of objects

s = ['a', 1, 4]

And I wish to get the result so:

[ ['x'], [1, 2, 3], ['a', 5, 6], [1, 7] ]

Is there a nice/pythonic way to do it ?

EDIT:

I want the head of each resulted list to be an element of s, and all these lists to keep the elements of initial list in the same order.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • 1
    So is it randomly split or is the second list the position of where to cut off individual lists? I'm only asking because there is no 4 in the first list – erdekhayser Mar 09 '13 at 14:59
  • Well do you wanna tell us what logic you are using to split the list? – IcyFlame Mar 09 '13 at 15:02
  • Something you want. [check this](http://stackoverflow.com/a/6696059/2115255) – Umair Saleem Mar 09 '13 at 15:03
  • s can contain any object. The problem is to split the list l using objects from the list s. – alinsoar Mar 09 '13 at 15:08
  • 1
    "The problem is to split the list l using objects from the list l." That doesn't say anything the original question doesn't. For example, unless I'm missing something, your example doesn't show what you want to happen if there are two objects in `s` contiguous in `l`. Do you want `['a', '1']` to give `[['a', '1']]` or `[['a'], ['1']]`? – DSM Mar 09 '13 at 15:10
  • edited the original question – alinsoar Mar 09 '13 at 15:15

2 Answers2

5

A generator would do that for you in a jiffy:

def split_on_members(seq, s):
    s = set(s)
    chunk = []
    for i in seq:
        if i in s and chunk:
            yield chunk
            chunk = []
        chunk.append(i)
    if chunk:
        yield chunk

which gives:

>>> list(split_on_members(l, s))
[['x'], [1, 2, 3], ['a', 5, 6], [1, 7]]

You could just loop over the generator without creating a full list of course:

>>> for group in split_on_members(l, s):
...     print group
... 
['x']
[1, 2, 3]
['a', 5, 6]
[1, 7]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
2

Try these 2 functions,

  1. The 'return' type

    def overlap_split_list(l,s):
        l1 = []
        l2 = []
        for i in l:
            if i in s:
                l1.append(l2)
                l2 = []
            l2.append(i)
        if l2: l1.append(l2)
        return l1
    
  2. The generator type

    def generator_overlap_split_list(l,s):
        l2 = []
        for i in l:
            if i in s:
                yield l2
                l2 = []
            l2.append(i)
        if l2: yield l2
    

For output (all will be same)

print overlap_split_list(l,s)    
print [i for i in generator_overlap_split_list(l,s)]
print list(generator_overlap_split_list(l,s))
pradyunsg
  • 18,287
  • 11
  • 43
  • 96
  • The `overlap_split_list` is actually the fastest of all functions submitted here. – Gandaro Mar 09 '13 at 15:43
  • @Gandaro Yes, because there are no "external forces" acting on it, i.e. In case of the generators, there is an individual call from outside, which is taking time (to make the call). – pradyunsg Mar 09 '13 at 16:01