问题
I'm trying to compare two dictionaries. My approach is to turn them into two separate lists of tuples and to then use the set module. Here is an illustration:
dict = {'red':[1,2,3],'blue':[2,3,4],'green':[3,4,5]}
dict1 = {'green':[3,4,5],'yellow':[2,3,4],'red':[5,2,6]}
intersection = set(set(dict.items()) & set(dict1.items()))
apparently, this is comparing two lists of tuples and python doesn't like that. I get a TypeError: 'list' is unhashable error (or similar wording).
I would like intersection to contain [('green',[3,4,5])]
. Any ideas?
回答1:
shared_keyvals = dict( (key, dict1[key])
for key in (set(dict1) & set(dict2))
if dict1[key] == dict2[key]
)
You can even make this into a function:
def shared_keyvals(dict1, dict2):
return dict( (key, dict1[key])
for key in (set(dict1) & set(dict2))
if dict1[key] == dict2[key]
)
Obviously, if you prefer to not have the output in dictionary form, you can just remove the dict()
call and replace with with list comprehension brackets ([]
) instead.
回答2:
Lists are mutable and, thus, not hashable. A set can be built only out of hashable items. Since values in the two dicts above are lists, sets cannot be built out of them. However, if one were to change the type of values from lists to tuples (which are immutable), one could build sets and perform set operations.
>>> dict1 = {'blue': (2, 3, 4), 'green': (3, 4, 5), 'red': (1, 2, 3)}
>>> dict2 = {'green': (3, 4, 5), 'yellow': (2, 3, 4), 'red': (5, 2, 6)}
>>> list(set(dict1.items()) & set(dict2.items()))
[('green', (3, 4, 5))]
来源:https://stackoverflow.com/questions/5062166/comparing-two-dictionaries-with-list-type-values