【问题标题】:Python 3.x, Trouble accessing key value with special characters in Python Dict (loaded through json)Python 3.x,在 Python Dict 中使用特殊字符访问键值时遇到问题(通过 json 加载)
【发布时间】:2026-02-13 02:40:02
【问题描述】:

我正在寻求帮助以 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 时引用密钥。

我已经尝试了 * 上的几个答案,但均无济于事。我需要使用相同的字符格式/编码来搜索 JSON/DICT,或者我需要遍历 JSON/DICT 并将所有键重新格式化为更易于搜索的格式/编码。

任何帮助完成任何一项都会让我高兴。感谢任何花时间给我今天生日礼物的人

【问题讨论】:

  • 一个问题,我不得不说!恭喜你:)
  • @m0m0e 生日快乐!
  • 非常感谢!

标签: json xml python-3.x unicode elementtree


【解决方案1】:

这可能是一个标准化问题。如果您 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 转换为分解或组合形式。

【讨论】:

  • 我相信你是正确的,这是一个规范化问题。这方面的证据是它可以使用一个花式 o 的密钥版本打印到 CMD,但不能使用另一个。 (它可以从 xml 文件打印密钥,但不能从 json 文件打印)。非常感谢您的意见。正如上面的海报所暗示的,通过确保将 json.load() 编码设置为 utf-8,我能够匹配所有键。现在我有一个更新的 cockatricecards.xml 并且只需要让我的更新程序成为公共消耗品。再次感谢您
【解决方案2】:

不确定您的问题出在哪里,以下适用于 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 开头(但这是另一个问题)

祝你好运!

【讨论】:

  • 它最终成为我在加载时更改的 json 编码并且它成功了,尽管我愿意打赌(并将调查更多)关于规范化的其他响应是根本问题。十分感谢你的帮助。我在 json.load() 上使用了 utf-8,所有的键似乎都找到了它们的归宿。我现在有一个可工作的 cockatrice 更新程序,只需将其设为公共消耗品。