Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge tuples with the same key

Tags:

python

tuples

How to merge a tuple with the same key

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

and turn them into

list_2 = [("AAA", [123, 456]), ("AAW", [147, 124])]
like image 294
Theprofessor14 Avatar asked Sep 22 '18 07:09

Theprofessor14


People also ask

How to combine tuples in Python list of tuples?

Combining tuples in list of tuples in Python 1 With for loop. In the below approach we create for loops that will create a pair of elements by taking each element of... 2 Example. 3 Output. 4 With product. The itertools module has iterator named product which creates Cartesian product of parameters passed onto... 5 Example. 6 Output. More ...

How do you iterate through a list of tuples?

Iterate over the list of tuples. Check if the first element of the tuple is present as a key in the dictionary or not. If it is present, then append the current tuple values without the first one to the previous values. If not present, then initialize the key with the current tuple elements including the first element.

Can a list contain tuples as its elements?

A list can contain tuples as its elements. In this article we will see how we can combine each element of a tuple with another given element and produce a list tuple combination. In the below approach we create for loops that will create a pair of elements by taking each element of the tuple and looping through the element in the list.

How do you append a tuple without the first element?

Iterate over the list of tuples. Check if the first element of the tuple is present as a key in the dictionary or not. If it is present, then append the current tuple values without the first one to the previous values.


Video Answer


4 Answers

The most performant approach is to use a collections.defaultdict dictionary to store data as an expanding list, then convert back to tuple/list if needed:

import collections

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

c = collections.defaultdict(list)
for a,b in list_1:
    c[a].extend(b)  # add to existing list or create a new one

list_2 = list(c.items())

result:

[('AAW', [147, 124]), ('AAA', [123, 456])]

note that the converted data is probably better left as dictionary. Converting to list again loses the "key" feature of the dictionary.

On the other hand, if you want to retain the order of the "keys" of the original list of tuples, unless you're using python 3.6/3.7, you'd have to create a list with the original "keys" (ordered, unique), then rebuild the list from the dictionary. Or use an OrderedDict but then you cannot use defaultdict (or use a recipe)

like image 146
Jean-François Fabre Avatar answered Oct 19 '22 03:10

Jean-François Fabre


You can use a dict to keep track of the indices of each key to keep the time complexity O(n):

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]
list_2 = []
i = {}
for k, s in list_1:
    if k not in i:
        list_2.append((k, s))
        i[k] = len(i)
    else:
        list_2[i[k]][1].extend(s)

list_2 would become:

[('AAA', [123, 456]), ('AAW', [147, 124])]
like image 24
blhsing Avatar answered Oct 19 '22 03:10

blhsing


You can create a dictionary and loop through the list. If the item present in dictionary append the value to already existing list else assign the value to key.

dict_1 = {}
for item in list_1:
    if item[0] in dict_1:
        dict_1[item[0]].append(item[1][0])
    else:
        dict_1[item[0]] = item[1]
list_2 = list(dict_1.items())
like image 33
S.Harish Avatar answered Oct 19 '22 02:10

S.Harish


Similarly to other answers, you can use a dictionary to associate each key with a list of values. This is implemented in the function merge_by_keys in the code snippet below.

import pprint

list_1 = [("AAA", [123]), ("AAA", [456]), ("AAW", [147]), ("AAW", [124])]

def merge_by_key(ts):

    d = {}
    for t in ts:
        key = t[0]
        values = t[1]
        if key not in d:
            d[key] = values[:]
        else:
            d[key].extend(values)

    return d.items()



result = merge_by_key(list_1)

pprint.pprint(result)
like image 1
Odysseas Avatar answered Oct 19 '22 02:10

Odysseas