不可散列类型:字典反转函数中的列表错误

Unhashable type: List error in dictionary invert function

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

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

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

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

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

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

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



    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()

</pre>

输出:



    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'

</pre>
	

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

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

无关,如果你想让 ("FIDE ID: 0147632DF") 成为一个元组,你需要一个尾随逗号:("FIDE ID: 0147632DF",)。或者,使用 2 元素元组可能更有意义,遵循其他元组的格式:("FIDE ID: ", "0147632DF")。或者,代替 2 元素元组的列表,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()