Amir Hossein
Amir Hossein

Reputation: 29

Find tuple in list with same first item and return another list

I have a list like this in Python:

[('a', 'b'), ('a', 'c'),('d','f')]

and I want join items that have same first item and result like this:

[('a', 'b', 'c'),('d','f')]

Upvotes: 1

Views: 314

Answers (3)

cglacet
cglacet

Reputation: 10962

I feel like the simplest solution is to build a dictionary in which:

  • keys are the first items in the tuples
  • values are lists comporting all second items from the tuples

Once we have that we can then build the output list:

from collections import defaultdict

def merge(pairs):
    mapping = defaultdict(list)
    for k, v in pairs:
        mapping[k].append(v)
    return [(k, *v) for k, v in mapping.items()]

pairs = [('a', 'b'), ('a', 'c'),('d','f')]
print(merge(pairs))

This outputs:

[('a', 'b', 'c'), ('d', 'f')]

This solution is in O(n) as we only iterate two times over each item from pairs.

Upvotes: 0

Thierry Lathuille
Thierry Lathuille

Reputation: 24281

Here is one way to do it. For efficiency, we build a dict with the first value as key. We keep the values in the order in which they appear (and the tuples in their original order as well, if you use Python >= 3.7 - otherwise you will have to use a collections.OrderedDict)

def join_by_first(sequences):
    out = {}
    for seq in sequences:
        try:
            out[seq[0]].extend(seq[1:])
        except KeyError:
            out[seq[0]] = list(seq)
    return [tuple(values) for values in out.values()]

join_by_first([('a', 'b'), ('a', 'c'),('d','f')])
# [('a', 'b', 'c'), ('d', 'f')]

Upvotes: 1

Patrick Artner
Patrick Artner

Reputation: 51683

You can not edit tuples - the are immuteable. You can use lists and convert all back to tuples afterward:

data = [('a', 'b'), ('a', 'c'),('d','f')]

new_data = []


for d in data                                             # loop over your data
    if new_data and new_data[-1][0] == d[0]:              # if something in new_data and 1st
        new_data[-1].extend(d[1:])                        # ones are identical: extend
    else:
        new_data.append( [a for a in d] )                 # not same/nothing in: add items

print(new_data)                   # all are lists

new_data = [tuple(x) for x in new_data]
print(new_data)                   # all are tuples again      

Output:

[['a', 'b', 'c'], ['d', 'f']]     # all are lists
[('a', 'b', 'c'), ('d', 'f')]     # all are tuples again   

See Immutable vs Mutable types

Upvotes: 0

Related Questions