Say I have a list like so:
[1, 4, None, 6, 9, None, 3, 9, 4 ]
I decide to split this into nested lists on None
, to get this:
[ [ 1, 4 ], [ 6, 9 ], [ 3, 9, 4 ] ]
Of course, I could have wanted to do this on (9, None)
in which case, we would have got:
[ [ 1, 4 ], [ 6 ], [ 3 ], [ 4 ] ]
This is trivial to do using list append through iteration ( in a for loop )
I am interested to know whether this can be done in something faster - like a list comprehension?
If not, why not ( for example, a list comprehension cannot return more than one list element per iteration? )
Something like this:
gets me:
The problem with trying to use a list comprehension for this is that the comprehension is inherently stateless, and you need state to perform the splitting operation. In particular, you need to remember, from one element to the next, what elements were found after the previous 'split' marker.
However, you could use one list comprehension to extract the indices of the split elements, and then another to use those indices to chop up the list. We need to translate the split indices into (begin, end) indices for the necessary 'pieces'. What we'll do is transform the list of split indices into two separate lists of 'begins' and 'ends', and then zip them together.
The whole thing looks like:
You could find the indices of the "delimiter" elements. For example, the indices of None are 2 and 5 (zero-based). You could use these, along with the length of the list, to construct a list of tuples
[ (0,1), (3,4), (6,8) ]
representing the start indices and end indices of the sublists. Then you can use a list comprehension over this list of tuples to extract sublists.Here's an implementation using reduce, with a few bells and whistles:
benchmark code:
Output on i3-530, Windows7, Python 3.1.2:
Slightly modified Ryan's code, hope you don't mind. ssplit was based on the idea of Karl. Added statements handling some special cases to became ssplit2 which is the best solution I may provide.