1

I have this array which contains some dictionaries :

a = [{'name': 'Peter', 'email': '', 'color': 'red'},
 {'name': 'Peter', 'email': '', 'color': 'red'},
 {'name': 'Peter', 'email': '', 'color': 'red'}]

But I tried to do this : list(set(a)) and it does not work unfortunately I get this :

TypeError: unhashable type: 'dict'

Do you know how can I solve this I mean I would like to have :

a = [{'name': 'Peter', 'email': '', 'color': 'red'}]

Thank you !

Dalvtor
  • 3,160
  • 3
  • 21
  • 36
  • What exactly do you want to accomplish? Your post and especially the question are unclear. – DYZ Jun 07 '19 at 01:24

3 Answers3

0

This will solve your problem:

[dict(t) for t in {tuple(d.items()) for d in a}]

This will convert the list of dictionaries to a list of tuples, each tuple contains the items of the dictionary. Now, tuples can be hashed, different from dictionaries. We remove using a set comprehension.

Another alternative would be:

set(tuple(d.items()) for d in a)

Which returns {(('name', 'Peter'), ('email', ''), ('color', 'red'))}, now you would need to reconstruct the dictionaries.

Vitor Falcão
  • 1,007
  • 1
  • 7
  • 18
0

This is not really a Django question, but a general Python question.

You cannot use a set to get unique members of any iterable if those members are not hashable.

One simple way is to use itertools.groupby in conjunction with sorting the outer list by each dict's values:

a = [{'name': 'Peter', 'email': '', 'color': 'red'},
 {'name': 'Peter', 'email': '', 'color': 'red'},
 {'name': 'Peter', 'email': '', 'color': 'red'}]

from itertools import groupby

uniques = [key for key, _ in groupby(sorted(a, key=lambda d: tuple(d.values())))]

print(uniques)

Output:

[{'name': 'Peter', 'email': '', 'color': 'red'}]
gmds
  • 19,325
  • 4
  • 32
  • 58
0

You can also exploit the fact that a dictionary cannot have repeating same keys. Specifically, you can use update

arr = [{'name': 'Peter', 'email': '', 'color': 'red'},
       {'name': 'Peter', 'email': '', 'color': 'red'},
       {'name': 'Peter', 'email': '', 'color': 'red'}]

arr1 = {}
for d in arr:
    for k, v in d.items():
        arr1.update({k: v})
print ([arr1])        
# [{'name': 'Peter', 'email': '', 'color': 'red'}]
Sheldore
  • 37,862
  • 7
  • 57
  • 71