Edit: this was based on the original question under the assumption that the data would be in one list, and not in multiple input lists. Editing the question made it clear that this is not so, so I would advise you to follow the decision of Janne Karila .
Assuming you know how many different values ββthere are, this is a good solution using the itertools
' grouper()
recipe :
import itertools def grouper(n, iterable, fillvalue=None): args = [iter(iterable)] * n return itertools.zip_longest(fillvalue=fillvalue, *args) data = ["date", "1a", "2a", "3a", "1b", "2b", "3b", "1c", "2c", "3c"] first = data.pop(0) print([list(zip(itertools.repeat(first), items)) for items in zip(*grouper(3, data))])
Gives us:
[ [('date', '1a'), ('date', '1b'), ('date', '1c')], [('date', '2a'), ('date', '2b'), ('date', '2c')], [('date', '3a'), ('date', '3b'), ('date', '3c')] ]
Note that this will populate lists with None
if the values ββare not enough.
Naturally, you can use the understanding of the generator instead of understanding the list , if you just want to iterate over it, for example, not displaying it, For example:
(zip(itertools.repeat(first), items) for items in zip(*grouper(3, data)))
Note that I'm using Python 3.x, so under 2.x, wherever I use zip()
, you probably want itertools.izip()
, and itertools.zip_longest()
will become itertools.izip_longest()
.
Note that the best way to do this is by assuming that you know what determines the value that should be in the first list, what should be in the second list, etc.
import itertools import operator data = ["date", "1a", "2a", "3a", "1b", "2b", "3b", "1c", "2c", "3c"] first = data.pop(0) print([list(zip(itertools.repeat(first), items)) for _, items in itertools.groupby(sorted(data), operator.itemgetter(0))])
What produces:
[ [('date', '1a'), ('date', '1b'), ('date', '1c')], [('date', '2a'), ('date', '2b'), ('date', '2c')], [('date', '3a'), ('date', '3b'), ('date', '3c')] ]
Naturally, this only works for this example, assuming that your real data is different, you need to change operator.itemgetter(0)
to a function that determines which list your item should be grouped into.
Please note that we can encapsulate our preliminary work:
def prefix(iterable, prefix): """Returns every element of an iterable prefixed with a given value."""
And then we just:
(prefix(items, first) for items in zip(*grouper(3, data)))
and
(prefix(items, first) for _, items in itertools.groupby(sorted(data), operator.itemgetter(0)))
This is more readable.