Reputation: 149
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])]
Upvotes: 13
Views: 6075
Reputation: 1060
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)
Upvotes: 1
Reputation: 159
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())
Upvotes: 1
Reputation: 106883
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])]
Upvotes: 5
Reputation: 140256
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)
Upvotes: 17