Python 为什么我会得到';不可损坏类型:dict';递归清理json对象时出错?

Python 为什么我会得到';不可损坏类型:dict';递归清理json对象时出错?,python,json,dictionary,typeerror,Python,Json,Dictionary,Typeerror,我试图清除json对象,方法是删除值为“N/a”、““-”或“”的键,并从任何列表中删除这些值。要清理的对象的示例: dirty = { 'name': {'first': 'Robert', 'middle': '', 'last': 'Smith'}, 'age': 25, 'DOB': '-', 'hobbies': ['running', 'coding', '-'], 'education': {'highschool': 'N/A', 'col

我试图清除json对象,方法是删除值为“N/a”、““-”或“”的键,并从任何列表中删除这些值。要清理的对象的示例:

dirty = {
    'name': {'first': 'Robert', 'middle': '', 'last': 'Smith'},
    'age': 25,
    'DOB': '-',
    'hobbies': ['running', 'coding', '-'],
    'education': {'highschool': 'N/A', 'college': 'Yale'}
}
我发现了一个类似的问题,并修改了解决方案,提供了以下功能:

def clean_data(value):
    """
    Recursively remove all values of 'N/A', '-', and '' 
    from dictionaries and lists, and return
    the result as a new dictionary or list.
    """
    missing_indicators = set(['N/A', '-', ''])
    if isinstance(value, list):
        return [clean_data(x) for x in value if x not in missing_indicators]
    elif isinstance(value, dict):
        return {
            key: clean_data(val)
            for key, val in value.items()
            if val not in missing_indicators
        }
    else:
        return value
但我从字典理解中得到了不可破坏的类型:dict错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-79-d42b5f1acaff> in <module>
----> 1 clean_data(dirty)

<ipython-input-72-dde33dbf1804> in clean_data(value)
     11         return {
     12             key: clean_data(val)
---> 13             for key, val in value.items()
     14             if val not in missing_indicators
     15         }

<ipython-input-72-dde33dbf1804> in <dictcomp>(.0)
     12             key: clean_data(val)
     13             for key, val in value.items()
---> 14             if val not in missing_indicators
     15         }
     16     else:

TypeError: unhashable type: 'dict'
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在里面
---->1清洁_数据(脏)
在clean_数据中(值)
11返回{
12键:清除数据(val)
--->13键,值为val.items()
14如果val不在缺少的_指示器中
15         }
英寸(.0)
12键:清除数据(val)
13键,值为val.items()
--->14如果val不在缺少的_指示器中
15         }
16其他:
TypeError:无法损坏的类型:“dict”

很明显,当val是一个dict时,我进行集合比较的方式与我认为的不一样。有人能给我一些启发吗?

乍一看,这似乎是一个问题:

if val not in missing_indicators
当您在
集合
上使用
中的
时,它将检查您询问的值是否在
集合
条目中。要成为Python中
dict
中的键或
集的成员,您使用的值必须是可散列的。通过对Python中的值运行
hash
,可以检查该值是否可哈希:

>>> hash(1)
1
>>> hash("hello")
7917781502247088526
>>> hash({"1":"2"})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
哈希(1) 1. >>>哈希(“你好”) 7917781502247088526 >>>散列({“1”:“2”}) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:无法损坏的类型:“dict”
在您的代码段中,
val
看起来像是一个
dict
,您正在询问Python这个
val
是否是
集合中存在的值之一。作为响应,Python尝试对
进行散列
val
,但失败了


您必须克服的障碍是,外部
dict
中的一些值本身就是
dict
,而其他值看起来像
list
str
int
。在每种情况下,您都需要不同的策略:检查
val
是什么类型的东西,然后相应地采取行动。

作为一种修复方法,您可以将
缺失的\u指标
更改为一个列表,除非性能非常关键。通过3个元素列表进行线性搜索并不是什么大不了的事。这很有效!非常感谢。我现在明白了,val对于set操作必须是可散列的——将缺少的_指示符更改为list type可以解决这个问题。我在帖子中也犯了一个错误:出于同样的原因,手动执行设置操作也会失败。我会把那部分删掉。