You group based on the key. If your input groups are always consistent, you can use itertools.groupby(), otherwise use a dictionary to group items. If order matters, use a dictionary that preserves the insertion order (> Python 3.6 dictor collections.OrderedDict).
Usage groupby():
from itertools import groupby
from operator import itemgetter
new = [(k, *zip(*(t[1:] for t in g))) for k, g in groupby(lst, key=itemgetter(0))]
Python 3 (..., * iterable) `.
:
groups = {}
for key, *values in lst:
groups.setdefault(key, []).append(values)
new = [(k, *zip(*v)) for k, v in groups.items()]
Python 3.6 .
:
>>> from itertools import groupby
>>> from operator import itemgetter
>>> lst = [(('a', 'b'), 1, 2), (('a', 'b'), 3, 4), (('b', 'c'), 5, 6)]
>>> [(k, *zip(*(t[1:] for t in g))) for k, g in groupby(lst, key=itemgetter(0))]
[(('a', 'b'), (1, 3), (2, 4)), (('b', 'c'), (5,), (6,))]
>>> groups = {}
>>> for key, *values in lst:
... groups.setdefault(key, []).append(values)
...
>>> [(k, *zip(*v)) for k, v in groups.items()]
[(('a', 'b'), (1, 3), (2, 4)), (('b', 'c'), (5,), (6,))]
Python 2, :
new = [(k,) + tuple(zip(*(t[1:] for t in g))) for k, g in groupby(lst, key=itemgetter(0))]
from collections import OrderedDict
groups = OrderedDict()
for entry in lst:
groups.setdefault(entry[0], []).append(entry[1:])
new = [(k,) + tuple(zip(*v)) for k, v in groups.items()]