amaatouq
amaatouq

Reputation: 2337

Python - List of unique dictionaries where each dictionary value is a list

Let's say I got a list of dictionaries like this:

[
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
{'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E','F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

and I need to obtain a list of unique dictionaries (removing the duplicates):

[
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

I tried

unique_solutions = list(set(val for dic in full_solutions_list for val in dic.values())) 

But the 'list' type of dictionary values are unhashable.

What would be an efficient way to do this? (the number of dictionaries is relatively large).

Upvotes: 1

Views: 98

Answers (2)

ankitpandey
ankitpandey

Reputation: 349

You are trying to iterate through the dictionary value which is causing you error. You can append dict to the list if the value is not present already.

unique_solutions=[]
[unique_solutions.append(val) for val in lst if val not in unique_solutions]

Result:

>>> print(unique_solutions)
[{'101': ['A', 'B'], '102': ['C'], '103': ['D'], '104': [], '105': [], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}, {'101': ['A'], '102': ['C'], '103': ['B'], '104': ['D'], '105': ['E'], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}]

Upvotes: 1

awarrier99
awarrier99

Reputation: 3855

You could just add a dict to your unique list if it is not already contained within it (note that I'm assuming you meant for the third item to have an 'E' in its deck list, otherwise it would not be a duplicate):

x = [
 {'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
 {'101': ['A'],
  '102': ['C'],
  '103': ['B'],
  '104': ['D'],
  '105': ['E'],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']},
{'101': ['A','B'],
  '102': ['C'],
  '103': ['D'],
  '104': [],
  '105': [],
  'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}
]

unique_solutions = []
for d in x:
    if d not in unique_solutions:
        unique_solutions.append(d)

Or, you could create something like a HashDict class which implements hashes (in my example, using tuples, but this could be done in different ways) and create a set:

class HashDict(dict):
    def __init__(self, d):
        for k, v in d.items():
            self[k] = v

    def __hash__(self):
        return hash(tuple((k, tuple(v)) for k, v in self.items()))

hdx = [HashDict(d) for d in x]
unique_solutions = list(set(hdx))

Both examples result in

>>> print(unique_solutions)
[{'101': ['A', 'B'], '102': ['C'], '103': ['D'], '104': [], '105': [], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}, {'101': ['A'], '102': ['C'], '103': ['B'], '104': ['D'], '105': ['E'], 'deck': ['E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']}]

Upvotes: 1

Related Questions