Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split list into lists based on a character occurring inside of an element

In a list like the one below:

biglist = ['X', '1498393178', '1|Y', '15496686585007',
           '-82', '-80', '-80', '3', '3', '2', '|Y', '145292534176372',
           '-87', '-85', '-85', '3', '3', '2', '|Y', '11098646289856',
           '-91', '-88', '-89', '3', '3', '2', '|Y', '35521515162112',
           '-82', '-74', '-79', '3', '3', '2', '|Z',
           '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']

There could be some numerical elements preceded by a character. I would like to break this into sub-lists like below:

smallerlist = [
 ['X', '1498393', '1'],
 ['Y', '1549668', '-82', '-80', '-80', '3', '3', '2', ''],
 ['Y', '1452925', '-87', '-85', '-85', '3', '3', '2', ''],
 ['Y', '3552151', '-82', '-74', '-79', '3', '3', '2', ''],
 ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']
]

As you can tell, depending upon the character, the lists could look similar. Otherwise they could have a different number of elements, or dissimilar elements altogether. The main separator is the "|" character. I have tried to run the following code to split up the list, but all I get is the same, larger, list within a list. I.e., list of len(list) == 1.

import itertools

delim = '|'
smallerlist = [list(y) for x, y in itertools.groupby(biglist, lambda z: z == delim)
                if not x]

Any ideas how to split it up successfully?

like image 797
omrakhur Avatar asked Jul 24 '17 12:07

omrakhur


People also ask

How do you split a list based on a condition in Python?

split() , to split the list into an ordered collection of consecutive sub-lists. E.g. split([1,2,3,4,5,3,6], 3) -> ([1,2],[4,5],[6]) , as opposed to dividing a list's elements by category. Discussion of the same topic on python-list. IMAGE_TYPES should be a set instead of a tuple: IMAGE_TYPES = set('.

How do you split a list into an element?

To split the elements of a list in Python: Use a list comprehension to iterate over the list. On each iteration, call the split() method to split each string. Return the part of each string you want to keep.

Can you split a list of lists in Python?

Split a List Into Even Chunks of N Elements in Python. A list can be split based on the size of the chunk defined. This means that we can determine the size of the chunk. If the subset of a list doesn't fit in the size of the defined chunk, fillers need to be inserted in the place of the empty element holders.


1 Answers

First, a quick oneliner, which is not an optimal solution in terms of space requirements, but it's short and sweet:

>>> smallerlist = [l.split(',') for l in ','.join(biglist).split('|')]
>>> smallerlist
[['X', '1498393178', '1'],
 ['Y', '15496686585007', '-82', '-80', '-80', '3', '3', '2', ''],
 ['Y', '145292534176372', '-87', '-85', '-85', '3', '3', '2', ''],
 ['Y', '11098646289856', '-91', '-88', '-89', '3', '3', '2', ''],
 ['Y', '35521515162112', '-82', '-74', '-79', '3', '3', '2', ''],
 ['Z', '0.0', '0.0', '0', '0', '0', '0', '0', '4', '0', '154']]

Here we join all elements of the big list by a unique non-appearing separator, for example ,, then split by |, and then split again each list into a sublist of the original elements.

But if you're looking for a bit more efficient solution, you can do it with itertools.groupby that will operate on an intermediate list, generated on fly with the breakby() generator, in which elements without | separator are returned as is, and those with separator are split into 3 elements: first part, a list-delimiter (e.g. None), and the second part.

from itertools import groupby

def breakby(biglist, sep, delim=None):
    for item in biglist:
        p = item.split(sep)
        yield p[0]
        if len(p) > 1:
            yield delim
            yield p[1]

smallerlist = [list(g) for k,g in groupby(breakby(biglist, '|', None),
                                          lambda x: x is not None) if k]
like image 140
randomir Avatar answered Oct 26 '22 18:10

randomir