1

I have a dictionary of lists and want to combine the keys which share duplicate lists into a seperate list within a dictionary that also contains the original list that they all share.

I have tried to use existing solutions that work for hashable type such as when the dictionary just contains strings as the values. Relevant SO question can be found here. Each time I attempt any of these solutions or any others I have tried using similar techniques all result in an unhashable type error.

Here is an example of what my dictionary looks like.

exampledict = {'FOO': [1, 2, 3, 4, 25, 9], 'BAR': [1, 2], 'BAZ': [1, 2], 'ABC': [1, 2, 3, 4, 25, 9]}

The correct output should be two dictionaries:

finaldict1 = {'keys': ['BAR', 'BAZ'], 'value': [1, 2]}
finaldict2 = {'keys': ['FOO', 'ABC'], 'value': [1, 2, 3, 4, 25, 9]}
Jack Sullivan
  • 199
  • 1
  • 1
  • 10
  • Have you tried anything yet? – Selcuk Aug 22 '19 at 05:11
  • In link given by you and your question difference is that value is list in your case and value is a dictionary in already answered question. This makes a difference. You will have to compare if values(lists) are equal or not – shantanu pathak Aug 22 '19 at 05:19

2 Answers2

2

you can try:

from operator import itemgetter
from itertools import groupby

final_dicts = [{'keys': [e[0] for e in v], 'value': k} for k, v in groupby(sorted(exampledict.items(), key=itemgetter(1)), key=itemgetter(1))]
finaldict1 , finaldict2 = final_dicts

print(finaldict1)
print(finaldict2)

output:

{'keys': ['BAR', 'BAZ'], 'value': [1, 2]}
{'keys': ['FOO', 'ABC'], 'value': [1, 2, 3, 4, 25, 9]}

in this case, it just happens that you have 2 dicts, but you can use the final_dicts variable as you want

kederrac
  • 16,819
  • 6
  • 32
  • 55
1

Use collections.defaultdict

Ex.

from collections import defaultdict
exampledict = {'FOO': [1, 2, 3, 4, 25, 9], 'BAR': [1, 2], 'BAZ': [1, 2], 'ABC': [1, 2, 3, 4, 25, 9]}
newMap = defaultdict(set)
for key, value in exampledict.items():
    newMap[tuple(value)].add(key)

result = [{'keys':list(newMap[x]),'value':list(x)} for x in newMap ]
print(result)

O/P:

[{'keys': ['FOO', 'ABC'], 'value': [1, 2, 3, 4, 25, 9]}, {'keys': ['BAR', 'BAZ'], 'value': [1, 2]}]
bharatk
  • 4,202
  • 5
  • 16
  • 30