不可哈希类型:'dict' 类型错误

3

假设我有这个字典:

items = {1: {'title': u'testing123', 'description': u'testing456'},
2: {'description': u'testing123', 'description': u'testing456'},
3: {'description': u'testing123', 'description': u'testing456'},
4: {'description': u'testing123', 'description': u'testing456'},
5: {'description': u'testing123', 'description': u'testing456'},
6: {'description': u'somethingelse', 'description': u'somethingelse'}}

我希望过滤掉重复的值,以便最终得到:

{1: {'title': u'testing123', 'description': u'testing456'}, 6: {'title': u'something', 'description': u'somethingelse'}}

我写了这段代码:
dic = {}

for key, value in items.items():
    if not set(value.values()).issubset(set(dic.values())):
        dic[key] = value

然而我收到了错误信息TypeError: unhashable type: 'dict'。我不确定为什么会出现这种情况以及如何解决它。

这是受到另一个问题的启发,以及我未能解决它的尝试。

3个回答

3

dic.values()返回字典的值列表。

>>> for key, value in items.items():
...     print dic.values()
...
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
>>>

因为字典是不可哈希的,所以你无法在字典上应用set。

顺便说一下,你可以通过以下方式解决此问题:

>>> dic = {}
>>> for key, value in items.items():
...     if not set(value.values()).issubset(set(sum([x.values() for x in dic.values()],[]))):
...         dic[key] = value
...
>>> dic
{1: {'description': u'testing456', 'title': u'testing123'}, 6: {'description':     u'somethingelse', 'title': u'somethingelse'}}
>>>

针对Python > 3.x版本

if not set(value.values()).issubset(set(sum([list(x.values()) for x in list(dic.values())],[]))):

当我运行代码时,我收到TypeError: can only concatenate list (not "dict_values") to list的错误。我使用的是Python 3.4版本。 - Morteza R
请尝试以下Python 3.4代码:如果不设置(set)值(value.values())是子集(issubset)总和(sum)的一部分([])的列表(list(dic.values())中的每个x.values()),则执行此操作。 - James Sapam
很好,现在它运行得很好。谢谢! - Morteza R

1

编辑:如果必须使用集合,正如其他人所指出的那样,您必须使用可哈希对象,例如元组:

unique_items = set()
for k, v in items.items():
    sorted_v = tuple(sorted((k2, v2) for k2, v2 in v.items()))
    unique_items.add(sorted_v)
unique_items = dict(unique_items)

给出了`unique_items`的值:
{1: {'description': u'testing456', 'title': u'testing123'},
 6: {'description': u'somethingelse', 'title': u'somethingelse'}}

如果items不是很大(或者至少预计输出的字典不会很大):
items = {1: {'title': u'testing123', 'description': u'testing456'},
2: {'title': u'testing123', 'description': u'testing456'},
3: {'title': u'testing123', 'description': u'testing456'},
4: {'title': u'testing123', 'description': u'testing456'},
5: {'title': u'testing123', 'description': u'testing456'},
6: {'title': u'somethingelse', 'description': u'somethingelse'}}

unique_items = {}
for k, v in items.items():
    if v not in unique_items.values():
        unique_items[k] = v

(假设你的字典示例中第一个键应该是title)。但是,如果在items中存在重复项,则无法预测此字典的键将是什么。

解决原始问题并不是我所询问的。请处理本问题的主要问题,即我收到错误的原因。 - Morteza R
啊 - 好的:我没意识到你在寻找一个基于set的解决方案。我已经编辑了我的答案来提供一个。 - xnx

0

你正在尝试创建一组字典,但这是不可能的,因为字典是不可哈希的(因为它们是可变的——当您修改/添加/删除字典中的键值对时,它们是否相等会发生变化)。

也许你可以使用元组来代替字典,将它们的值放入集合中,例如:if not set((v['description_a'], v['description_b]) for v in value.values()).issubset((v['description_a'], v['description_b]) for v in set(dic.values())): 或类似的方法?


那不是一组字典,而是一组字典值。差别很大! - Morteza R
实际上,代码的那部分运行得非常好。错误出在我执行赋值dic[key] = value的那一部分。 - Morteza R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接