dearprudence
dearprudence

Reputation: 157

Flattening tuple with repeating key?

I’m trying to turn

x = [((1, ‘code’, ‘XXXX’), (1, ‘ref’, ‘112B’))]

into [(1, (‘code’, ‘XXXX’), (‘ref’, ‘112B’))]

Basically the first number is the key.

I tried using itertools.groupby function but it became a mess on my end.

Upvotes: 0

Views: 73

Answers (2)

RoadRunner
RoadRunner

Reputation: 26315

If you want to still use itertools.groupby(), then you can try this solution. It first flattens the list of nested tuples to a list of tuples using itertools.chain.from_iterable(), then applies groupby() to group by the first item in each tuple. The groupby key is accessed with operator.itemgetter. Other option is to use key=lambda x: x[0].

from itertools import groupby, chain
from operator import itemgetter

x = [((1, "code", "XXXX"), (1, "ref", "112B"))]

groups = [
    (k, *tuple(x[1:] for x in g))
    for k, g in groupby(chain.from_iterable(x), key=itemgetter(0))
]

print(groups)

Output:

[(1, ('code', 'XXXX'), ('ref', '112B'))]

Note: This assumes your initial tuples are sorted. If they are not you can apply sorted():

groups = [
    (k, *tuple(x[1:] for x in g))
    for k, g in groupby(sorted(chain.from_iterable(x)), key=itemgetter(0))
]

Upvotes: 1

Keyur Potdar
Keyur Potdar

Reputation: 7238

You can first convert the list into a temporary dictionary using collections.defaultdict and then convert it into the format you want.

from collections import defaultdict

x = [((1, 'code', 'XXXX'), (1, 'ref', '112B'))]
temp = defaultdict(list)

for t in x[0]:
    temp[t[0]].append(t[1:])

print(temp)
# defaultdict(<class 'list'>, {1: [('code', 'XXXX'), ('ref', '112B')]})

final = [(k, *v) for k, v in temp.items()]
print(final)
# [(1, ('code', 'XXXX'), ('ref', '112B'))]

Upvotes: 3

Related Questions