【问题标题】:Unhashable type: List error in dictionary invert function不可散列的类型:字典反转函数中的列表错误
【发布时间】:2021-06-16 13:25:07
【问题描述】:

我正在做一项学校作业,要求我:

1) 将我之前创建的字典作为字符串写入文件。

2)然后再次将该字典导入python并反转它

3)将倒排字典写入新文件。

我之前问过一个关于这个程序的问题并得到了很好的答案,但我仍然很难解决一个错误。当我尝试运行程序时,我收到一个类型错误:不可散列类型:'list'。我假设它与反转功能有关。

当我使用 ChessPlayerProfile 字典在单独的脚本中运行该函数时,它似乎工作正常。但是当我尝试通过 Read_Invert_Write 函数输出中的返回字典在此脚本中使用它时,我得到了错误。

任何想法我做错了什么?任何帮助,将不胜感激。这是代码和输出:



    import os
    import json
    
    ChessPlayerProfile = {
        "Matt": [("Rating: ", 2200), ("FIDE ID: 0147632DF"), ("Member Status: ", True)],
        "Will": [("Rating: ", 2200), ("FIDE ID: 3650298MK"), ("Member Status: ", False)],
        "Jithu": [("Rating: ", 1900), ("FIDE ID: 5957200LH"), ("Member Status: ", True)],
        "Lisa": [("Rating: ", 2300), ("FIDE ID: 7719328CX"), ("Member Status: ", False)],
        "Nelson": [("Rating: ", 2500), ("FIDE ID: 6499012XX"), ("Member Status: ", True)],
        "Miles": [("Rating: ", 1600), ("FIDE ID: 4392251TJ"), ("Member Status: ", True)],
    }
    
    
    def write2file():
        with open("chessdict.txt", "w+") as f:
            json.dump(ChessPlayerProfile, f)
    
    
    
    def Read_Invert_Write():
        with open("chessdict.txt", "r") as f:
            Content = (json.load(f))
            Content = dict(Content)
            invert(Content)
            with open("newoutput.txt", "w+") as f:
                json.dump(Content, f)
    
    
    
    def invert(d):
        inverse = dict()
        for key in d:
            val = d[key]
            for item in val:
                if item not in inverse:
                    inverse[item] = [key]
                else:
                    inverse[item].append(key)
        print(inverse)
        return inverse
    
    
    def main():
        write2file()
        Read_Invert_Write()
    main()

输出:



    Traceback (most recent call last):
      File "/home/vigz/PycharmProjects/pythonProject/copytest2.py", line 46, in 
        main()
      File "/home/vigz/PycharmProjects/pythonProject/copytest2.py", line 45, in main
        Read_Invert_Write()
      File "/home/vigz/PycharmProjects/pythonProject/copytest2.py", line 24, in Read_Invert_Write
        invert(Content)
      File "/home/vigz/PycharmProjects/pythonProject/copytest2.py", line 35, in invert
        if item not in inverse:
    TypeError: unhashable type: 'list'

【问题讨论】:

    标签: python dictionary hash


    【解决方案1】:

    您能补充一下您的预期输出吗?

    您看到错误是因为在 dict 中,键必须是可散列数据类型。 lists are not hashable(抽象地说,不可变)

    所以要让你的程序运行没有错误。你可以试试这个。 但是从输出来看,我认为这不是您希望程序执行的操作

    import os
    import json
        
    ChessPlayerProfile = {
        "Matt": [("Rating: ", 2200), ("FIDE ID: 0147632DF"), ("Member Status: ", True)],
        "Will": [("Rating: ", 2200), ("FIDE ID: 3650298MK"), ("Member Status: ", False)],
        "Jithu": [("Rating: ", 1900), ("FIDE ID: 5957200LH"), ("Member Status: ", True)],
        "Lisa": [("Rating: ", 2300), ("FIDE ID: 7719328CX"), ("Member Status: ", False)],
        "Nelson": [("Rating: ", 2500), ("FIDE ID: 6499012XX"), ("Member Status: ", True)],
        "Miles": [("Rating: ", 1600), ("FIDE ID: 4392251TJ"), ("Member Status: ", True)],
    }
        
        
    def write2file():
        with open("chessdict.txt", "w+") as f:
            json.dump(ChessPlayerProfile, f)
    
    
    
    def Read_Invert_Write():
        with open("chessdict.txt", "r") as f:
            Content = (json.load(f))
            print(Content['Matt'])
            invert(Content)
            with open("newoutput.txt", "w+") as f:
                json.dump(Content, f)
    
    
    
    def invert(d):
        inverse = dict()
        for key in d:
            val = d[key]
            for item in val:
                if tuple(item) not in inverse.keys():
                    inverse[tuple(item)] = [key]
                else:
                    inverse[tuple(item)].append(key)
        print(inverse)
        return inverse
        
        
    def main():
        write2file()
        Read_Invert_Write()
    main()
    
    

    【讨论】:

    • 感谢您的回复。我试图让它对字典做的是反转键和值,因此新文件中的字典输出如下所示: {('Rating: ', 2200): ['Matt', 'Will'], ' FIDE ID: 0147632DF': ['Matt'], ('Member Status: ', True): ['Matt', 'Jithu', 'Nelson'], 'FIDE ID: 3650298MK': ['Will'], ( '会员状态:', False): ['Will', 'Lisa'], ('Rating: ', 1900): ['Jithu'], 'FIDE ID: 5957200LH': ['Jithu'], ('Rating : ', 2300): ['Lisa'], 'FIDE ID: 7719328CX': ['Lisa'], ('Rating: ', 2500): ['Nelson'], 'FIDE ID: 6499012XX': ['Nelson ']}
    • 噢噢!这虽然有效!添加 inverse[tuple(item)] = [key] 但没有 invert(Content[Matt]) 更改后,我得到了正确的输出。惊人的!谢谢你。现在我们又开始营业了。
    【解决方案2】:

    JSON 没有单独的列表或元组类型。它基于 Javascript,而不是 Python。 JSON 有一个单一的序列类型,JSON 数组,Python json 模块将列表和元组序列化为 JSON 数组。

    当您加载序列化的 JSON 时,JSON 数组会被反序列化为 Python 列表。这意味着您的新 dict 的值现在是列表列表而不是元组列表。当您运行 for item in val 循环时,item 是一个列表而不是一个元组,if item not in inverse 是尝试使用不可散列键执行字典查找。

    不相关,如果您的意思是 ("FIDE ID: 0147632DF") 是一个元组,您需要一个尾随逗号:("FIDE ID: 0147632DF",)。或者,使用 2 元素元组可能更有意义,遵循其他元组的格式:("FIDE ID: ", "0147632DF")。或者,代替 2 元素元组的列表,dict 可能是更方便的数据表示。

    【讨论】:

    • 非常真实!我已将这些 FIDE ID 转换为元组中的两个字符串以匹配其余部分。但据我了解,只要我使用 JSON 序列化字典,无论我做什么似乎都无法反转该字典?
    • @VigzMcHardthrust:您不必保留json.loads 为您提供的数据表示。如果适合您的用例,您可以执行诸如将列表转换为元组之类的操作。
    • 您对我理解这一点非常有帮助。我很感激。
    猜你喜欢
    • 2019-08-29
    • 2016-01-11
    • 2023-03-06
    • 2017-03-11
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多