Python 3.x,无法访问 Python Dict 中带有特殊字符的键值(通过 json 加载)

Python 3.x, Trouble accessing key value with special characters in Python Dict (loaded through json)

我正在寻求帮助以 Python 3.x 字典格式访问具有特殊字符(重音字母等)的键值。所以这就是我想要完成的事情:

我有一个 .xml 文件,我使用 ElementTree 将其解析为 Python:

...
    tree = ElementTree.parse(fileNamePath)
...

来源是一个名为 Cockatrice 的程序。这是他们的 card.xml 文件。

我有一个 .json 文本文件,我用 json.load(open(fileName)).

加载了它

来源是:https://mtgjson.com/json/AllCards-x.json.zip

这两个数据库都包含超过 16,000 个条目,对我来说太麻烦了,无法在我必须使用的旧 PC 上轻松地一次打印出来。另外,对于一些特殊字符,CMD 并不总是愿意打印它们。

总之...

我使用在 XML 文件中找到的名称作为搜索 JSON(转换为 DICT)键时使用的变量。

cardName=root[1][loop_control01].find('name').text

然后,我使用该名称从 JSON/DICT 中提取我想要的信息,并且大多数情况下它工作得很好,但当它得到一个带有特殊字符的名称时除外。一个不断弹出的例子是 Bösium Strip.

错误消息是关键错误:

KeyError: 'Bösium Strip'

我已通过记事本手动查看密钥,确认该密钥存在于 JSON 中。在 XML 文件中,文本拼写为:

...
  <card>
     <name>Bösium Strip</name>...

并且在 JSON 文件中拼写为:

...
    "Bösium Strip":{
        "layout":"normal",...

虽然我确实知道在 CMD 中打印这些字符的问题,但这似乎不是这里的问题,因为我没有将它们打印到屏幕上。我只需要能够在搜索 JSON/DICT.

时引用密钥

我已经尝试了在 Whosebug 上找到的几个答案,但都无济于事。我要么需要使用相同的 format/encoding 字符搜索 JSON/DICT,要么我需要遍历 JSON/DICT 并将所有键重新格式化为更易于搜索的 format/encoding。

任何帮助完成任何一个都会让我开心。感谢所有花时间给我一个很好的解决方案的人 - 今天是我的生日礼物 <3

不确定您的问题出在哪里,以下适用于 python 3.4.2

# -*- coding: utf-8 -*-
import json

jsonstring = """
[{
    "Bösium Strip": {
        "layout": "normal"
    },
    "test": {
        "hello1": "hello2"
    }
}]
"""
#data is a now a single element list, element containing dictionary
data = json.loads(jsonstring)

#both the following works
print(data[0].get('test', ''))
print(data[0].get('Bösium Strip', ''))

#the following works as well
keys = list(data[0].keys())
for key in keys:
    print(key)
    print(data[0].get(key))

但是这个例子使用的是 json.loads() 而不是 json.load() 后者将获取一个文件对象,你可能需要尝试该对象的编码,例如:

json.load(open(filename, 'r', encoding = 'utf-8'))

我刚刚检查了一些自己的代码,我是这样做的:

with open(filename, 'r', encoding = e) as openfileobject:
    data = openfileobject.read()
    data = _check_json_data(data)  #this is my own check
    data = json.loads(data)

我可以将 e 设置为文件的正确编码,然后我检查数据以验证它是否有效 json 开始(但这是另一个问题)

祝你好运!

这可能是规范化问题。如果您 ascii() 字典中的键,您可以查看您的键与字典中的键是否不同。

例如:

>>> s = 'Bösium Strip'
>>> ascii(s)
"'B\xf6sium Strip'"
>>> import unicodedata as ud
>>> t = ud.normalize('NFD',s)
>>> t
'Bösium Strip'
>>> s
'Bösium Strip'
>>> s==t
False
>>> ascii(s)
"'B\xf6sium Strip'"
>>> ascii(t)
"'Bo\u0308sium Strip'"

s 使用单个 Unicode 字符,而 t 使用带有 o 的组合字符。它们显示相同但不比较相同,但您可以使用 unicodedata.normalizeNFDNFC 转换为分解或组合形式。