cfollenf
cfollenf

Reputation: 63

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?

Upvotes: 6

Views: 443

Answers (2)

Kasravnd
Kasravnd

Reputation: 107347

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')]

Upvotes: 4

thefourtheye
thefourtheye

Reputation: 239573

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).

Upvotes: 4

Related Questions