【问题标题】:Why do I get 'unhashable type: dict' error when recursively cleaning json object?递归清理 json 对象时,为什么会出现“unhashable type: dict”错误?
【发布时间】:2021-06-11 12:05:17
【问题描述】:

如果键的值为“N/A”、“-”或“”,我正在尝试通过删除键来清理 json 对象,并且同样从任何列表中删除这些值中的任何一个。清洗对象示例:

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'

显然,当 val 是一个字典时,我进行集合比较的方式并不像我认为的那样工作。谁能赐教?

【问题讨论】:

    标签: python json dictionary typeerror


    【解决方案1】:

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

    if val not in missing_indicators
    

    当您在set 上使用in 时,它会检查您询问的值是否在set 条目中。要成为 dict 中的键或 Python 中 set 的成员,您使用的值必须是 hashable。您可以通过在其上运行 hash 来检查 Python 中的值是否可散列:

    >>> hash(1)
    1
    >>> hash("hello")
    7917781502247088526
    >>> hash({"1":"2"})
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unhashable type: 'dict'
    

    在您的 sn-p 中,看起来 valdict,而您正在询问 Python 这个 val 是否是 set 中的 之一。作为响应,Python 尝试 hash val,但失败了。

    您必须克服的障碍是 一些 在您的外部 dict 中的值本身就是 dict,而其他值看起来像 liststr 或 @987654339 @。在每种情况下,您都需要不同的策略:检查 val 是什么类型的事物,然后采取相应措施。

    【讨论】:

    • 作为修复,您可以将missing_indicators 更改为列表,除非性能绝对关键。通过 3 元素列表进行线性搜索没什么大不了的。
    • 这行得通!谢谢你。我现在明白了 val 对于集合操作必须是可散列的——将 missing_indicators 更改为列表类型可以解决问题。我在帖子中也犯了一个错误:出于同样的原因,手动执行设置操作也会失败。我会编辑那部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2011-01-30
    • 2014-07-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    相关资源
    最近更新 更多