2

I looked online and cant seem to understand much of it. im new to python and was wondering how i can fix this.

when running:

results = getRecommendations(userCompare[0], userCompare[0]['1'], sim_distance)

i get error:

    TypeError                                 Traceback (most recent call last)
<ipython-input-147-4d74cac55074> in <module>()
----> 1 results = getRecommendations(userCompare[0], userCompare[0]['1'], sim_distance)

<ipython-input-54-5f2d7e0dd3ba> in getRecommendations(data, person, similarity)
      5     for other in data:
      6         if other==person: continue #dont compare self
----> 7         sim=similarity(data, person, other)
      8         if sim<=0: continue #ignore scores of 0 or lower
      9         for item in data[other]:

<ipython-input-146-b30288308fee> in sim_distance(data, c1, c2)
      2 def sim_distance(data, c1, c2):
      3     si = {} #get the list of shared items
----> 4     for item in data[c1]:
      5         if item in data[c2]:
      6             si[item] = 1

TypeError: unhashable type: 'dict'

to create userCompare i did the following:

 movies = {}
    prefsList = []
    def loadMovieLens(path = directory):
        # Get movie titles
        for line in open(path + 'u.item'):
            (id, title) = line.split('|')[0:2]
            movies[id] = title 
        # Load data
        for k in range(len(centroidsM)):
            prefs ={}
            for rows in range(len(centroidsM[k])):
                for columns in range(len(centroidsM[k][0,:])):
                    user = str(rows+1)
                    movieid =str(columns+1)
                    prefs.setdefault(user,{})
                    prefs[user][movies[movieid]] = float(centroidsM[k][rows,columns])
            prefsList.append(prefs)
        return prefsList

I basically had an array of centroids with different K values, each K value has is a kx1682 matrix (k meaning number of clusters) so i loaded that into a list of dicts. i hope this makes sense. im starting to hate python or atleast dicts.

2 Answers 2

1

You can't use a dict as a dictionary key. What would happen if I did:

d = {}
k1 = {1: 2}
k2 = {2: 1}

d[k1] = "a"
d[k2] = "b"

k1[2] = 1
k2[1] = 2

I now have k2 == k1, so what does d[{1:2, 2:1}] do? Well, that's why you can't use a dict as a key.

If you really need to do that (e.g. to use in a Counter), here's an option: freezing the dict:

#coding:utf-8
FROZEN_TAG = "__frozen__"


def freeze_dict(obj):
    if isinstance(obj, dict):
        dict_items = list(obj.items())
        dict_items.append((FROZEN_TAG, True))
        return tuple([(k, freeze_dict(v)) for k, v in dict_items])
    return obj


def unfreeze_dict(obj):
    if isinstance(obj, tuple):
        if (FROZEN_TAG, True) in obj:
            out = dict((k, unfreeze_dict(v)) for k, v in obj)
            del out[FROZEN_TAG]
            return out
    return obj

It's from here.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! actually i figured out my problem... i was suppose to put in '1' or whatever variable in the 2nd argument when calling the function.. saved me alot of time and frustration
That's a good alternative idea. An out-of-the-box way to make "hashable-dicts" is to just json.dump() your dict before using it as a key.
1

You're getting that error because you are using an "unhashable" value (dict) as a dictionary key.

For example:

{dic():1}

Will give then same error.

Dictionaries cannot be used for keys, since they are mutable. Allowing mutable keys would wreak havoc with the dictionary, since it would not know when the keys had changed, so lookups would be impossible.

1 Comment

Generally, mutability != hashability. It's fine to use a mutable object as a key as long as it provides a consistent hash function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.