Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting a list into uneven tuples

I'm trying to split a list of strings into a list of tuples of uneven length containing these strings, with each tuple containing strings initially separated with blank strings. Basically I'd need the parameterized split that I could apply to lists. If my initial list looks like:

init = ['a', 'b', '', 'c', 'd e', 'fgh', '', 'ij', '', '', 'k', 'l', '']

The last element of this list is always a closing ''. There can be consecutive ''s which shall be considered as singles. The result I need is:

end = [('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')]

I already have ugly code that does the job and gets out of range once the list is fully popped out:

end = []
while init[-1] == u'':
 init.pop()
 l = []
 while init[-1] != u'':
  l.append(init.pop())
 end.append(tuple(l))

I'd like to use comprehensions, but having unsuccessfully tried unpacking argument lists, reversing self-referenced lists, using deque queues, and various code smells, I'm now doubting whether it makes sense looking for a (nested) comprehension solution?

like image 748
Felix Avatar asked Sep 01 '16 16:09

Felix


People also ask

How do you split a list of tuples?

To split a tuple, just list the variable names separated by commas on the left-hand side of an equals sign, and then a tuple on the right-hand side.

Can you split () a list in Python?

Python String split() MethodThe split() method splits a string into a list. You can specify the separator, default separator is any whitespace. Note: When maxsplit is specified, the list will contain the specified number of elements plus one.


2 Answers

You can use itertools.groupby function to group the elements based on their sizes, like this

>>> from itertools import groupby
>>> init = ['a', 'b', '', 'c', 'd e', 'fgh', '', 'ij', '', '', 'k', 'l', '']
>>> [tuple(g) for valid, g in groupby(init, key=lambda x: len(x) != 0) if valid]
[('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')]

This basically groups the elements based on their lengths. If the length of the item is not equal to zero, they will be put in a group, till an element from another group is met. The key function would return True for the group of elements whose length is not equal to zero, False otherwise. We ignore the group with False (hence the check if valid).

like image 89
thefourtheye Avatar answered Sep 29 '22 16:09

thefourtheye


Here is a more concise and general approach with groupby if you want to split your list with a special delimiter:

>>> delimiter = ''
>>> [tuple(g) for k, g in groupby(init, delimiter.__eq__) if not k]
[('a', 'b'), ('c', 'd e', 'fgh'), ('ij',), ('k', 'l')]
like image 44
Mazdak Avatar answered Sep 29 '22 15:09

Mazdak