Python dictionary : TypeError: unhashable type: 'list'

PythonHashDictionary

Python Problem Overview


I'm having troubles in populating a python dictionary starting from another dictionary.

Let's assume that the "source" dictionary has string as keys and has a list of custom objects per value.

I'm creating my target dictionary exactly as I have been creating my "source" dictionary how is it possible this is not working ?

I get

TypeError: unhashable type: 'list'

Code :

aTargetDictionary = {}
for aKey in aSourceDictionary:
    aTargetDictionary[aKey] = []
    aTargetDictionary[aKey].extend(aSourceDictionary[aKey])

The error is on this line : aTargetDictionary[aKey] = []

Python Solutions


Solution 1 - Python

The error you gave is due to the fact that in python, dictionary keys must be immutable types (if key can change, there will be problems), and list is a mutable type.

Your error says that you try to use a list as dictionary key, you'll have to change your list into tuples if you want to put them as keys in your dictionary.

According to the python doc :

> The only types of values not acceptable as keys are values containing > lists or dictionaries or other mutable types that are compared by > value rather than by object identity, the reason being that the > efficient implementation of dictionaries requires a key’s hash value > to remain constant

Solution 2 - Python

This is indeed rather odd.

If aSourceDictionary were a dictionary, I don't believe it is possible for your code to fail in the manner you describe.

This leads to two hypotheses:

  1. The code you're actually running is not identical to the code in your question (perhaps an earlier or later version?)

  2. aSourceDictionary is in fact not a dictionary, but is some other structure (for example, a list).

Solution 3 - Python

As per your description, things don't add up. If aSourceDictionary is a dictionary, then your for loop has to work properly.

>>> source = {'a': [1, 2], 'b': [2, 3]}
>>> target = {}
>>> for key in source:
...   target[key] = []
...   target[key].extend(source[key])
... 
>>> target
{'a': [1, 2], 'b': [2, 3]}
>>> 

Solution 4 - Python

It works fine : http://codepad.org/5KgO0b1G, your aSourceDictionary variable may have other datatype than dict

aSourceDictionary = { 'abc' : [1,2,3] , 'ccd' : [4,5] }
aTargetDictionary = {}
for aKey in aSourceDictionary:
        aTargetDictionary[aKey] = []
        aTargetDictionary[aKey].extend(aSourceDictionary[aKey])
print aTargetDictionary

Solution 5 - Python

You can also use defaultdict to address this situation. It goes something like this:

from collections import defaultdict

#initialises the dictionary with values as list
aTargetDictionary = defaultdict(list)

for aKey in aSourceDictionary:
    aTargetDictionary[aKey].append(aSourceDictionary[aKey])

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncodeJackView Question on Stackoverflow
Solution 1 - PythonCédric JulienView Answer on Stackoverflow
Solution 2 - PythonNPEView Answer on Stackoverflow
Solution 3 - PythonronakgView Answer on Stackoverflow
Solution 4 - PythonDhruvPathakView Answer on Stackoverflow
Solution 5 - PythonArchita SundarayView Answer on Stackoverflow