Python - Join Tuples If Similar Initial Element
Given a list of tuples, combine (or join) all tuples that share the same first element into a single tuple. The order of remaining elements should be preserved. For Example:
Input: [(5, 6), (5, 7), (5, 8), (6, 10), (7, 13)]
Output: [(5, 6, 7, 8), (6, 10), (7, 13)]
Using defaultdict + loop
from collections import defaultdict
t = [(5, 6), (5, 7), (6, 8), (6, 10), (7, 13)]
mapp = defaultdict(list)
for k, v in t:
mapp[k].append(v)
res = [(k, *v) for k, v in mapp.items()]
print(res)
Output
[(5, 6, 7), (6, 8, 10), (7, 13)]
Explanation:
- defaultdict(list): creates empty lists automatically.
- mapp[k].append(v): groups values by their first element.
- [(k, *v) ...]: converts grouped data back to tuples.Using dictionary + list comprehension
Using itertools.groupby()
groupby() from the itertools module groups consecutive elements sharing the same key ideal when the input list is sorted by the first element.
from itertools import groupby
t = [(5, 6), (5, 7), (6, 8), (6, 10), (7, 13)]
res = []
for k, g in groupby(t, key=lambda x: x[0]):
vals = [v for _, v in g]
res.append((k, *vals))
print(res)
Output
[(5, 6, 7), (6, 8, 10), (7, 13)]
Explanation:
- groupby(t, key=lambda x: x[0]): groups by first element.
- vals = [v for _, v in g]: collects second elements.
- res.append((k, *vals)): forms combined tuples.
Using Dictionary + List Comprehension
Using a simple dictionary to accumulate values by their first element provides an easy and readable approach.
t = [(5, 6), (5, 7), (6, 8), (6, 10), (7, 13)]
temp = {}
for x in t:
temp[x[0]] = temp.get(x[0], []) + list(x[1:])
res = [(k,) + tuple(v) for k, v in temp.items()]
print(res)
Output
[(5, 6, 7), (6, 8, 10), (7, 13)]
Explanation:
- temp.get(x[0], []): Returns current values or initializes an empty list.
- + list(x[1:]): Adds tuple elements to the existing list.
- (k,) + tuple(v): Combines key and grouped values.
Using Recursion
Recursion can be used to merge consecutive tuples dynamically by checking adjacent pairs and combining their values.
def join_tup(t, i):
if i == len(t) - 1:
return t
elif t[i][0] == t[i + 1][0]:
t[i] += t[i + 1][1:]
t.pop(i + 1)
return join_tup(t, i)
else:
return join_tup(t, i + 1)
t = [(5, 6), (5, 7), (6, 8), (6, 10), (7, 13)]
res = join_tup(t, 0)
print(res)
Output
[(5, 6, 7), (6, 8, 10), (7, 13)]
Explanation:
- if t[i][0] == t[i + 1][0]: Checks if consecutive tuples share the same key.
- t[i] += t[i + 1][1:]: Merges next tuple’s values.
- t.pop(i + 1): Removes the merged tuple.