【问题标题】:Dict not hashable python字典不可散列的python
【发布时间】:2013-12-05 14:39:36
【问题描述】:

我上网查了一下,好像不太明白。我是 python 新手,想知道如何解决这个问题。

运行时:

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

我得到错误:

    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'

要创建 userCompare,我做了以下操作:

 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

我基本上有一个具有不同 K 值的质心数组,每个 K 值都有一个 kx1682 矩阵(k 表示簇数),所以我将它加载到一个字典列表中。我希望这是有道理的。我开始讨厌 python 或至少 dicts。

【问题讨论】:

    标签: python dictionary hash numpy


    【解决方案1】:

    您不能将dict 用作字典键。如果我这样做会发生什么:

    d = {}
    k1 = {1: 2}
    k2 = {2: 1}
    
    d[k1] = "a"
    d[k2] = "b"
    
    k1[2] = 1
    k2[1] = 2
    

    我现在有了k2 == k1,那么d[{1:2, 2:1}] 有什么作用呢?嗯,这就是为什么你不能使用 dict 作为密钥的原因。

    如果您确实需要这样做(例如,在Counter 中使用),这里有一个选项:冻结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
    

    来自here

    【讨论】:

    • 谢谢!实际上我发现了我的问题......我应该在调用函数时在第二个参数中输入“1”或任何变量......为我节省了很多时间和挫折
    • 这是一个不错的替代方案。制作“hashable-dicts”的开箱即用方法是在将其用作密钥之前将 json.dump() 设置为您的 dict
    【解决方案2】:

    您收到该错误是因为您使用“不可散列”值 (dict) 作为字典键。

    例如:

    {dic():1}
    

    会给出同样的错误。

    字典不能用于键,因为它们是可变的。允许可变键会对字典造成严重破坏,因为它不知道键何时更改,因此不可能进行查找。

    【讨论】:

    • 一般来说,mutability != hashability。可以使用可变对象作为键,只要它提供一致的哈希函数即可。
    猜你喜欢
    • 2010-11-12
    • 2012-01-21
    • 2012-04-20
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多