我在使用python解析JSON时遇到了问题,现在我被卡住了 问题是我的JSON实体并不总是一样的。 JSON类似于:
"entries":[
{
"summary": "here is the sunnary",
"extensions": {
"coordinates":"coords",
"address":"address",
"name":"name"
"telephone":"123123"
"url":"www.blablablah"
},
}
]
我可以浏览JSON,例如:
for entrie in entries:
name =entrie['extensions']['name']
tel=entrie['extensions']['telephone']
问题来了,因为有时,JSON没有所有“字段”,例如,telephone
字段,有时会丢失,因此,脚本会因KeyError
而失败,因为密钥此条目中缺少电话
所以,我的问题是:如何运行此脚本,留下缺少电话的空白区域?
我试过了:
if entrie['extensions']['telephone']:
tel=entrie['extensions']['telephone']
但我认为不行。
答案 0 :(得分:14)
使用dict.get
代替[]
:
entries['extensions'].get('telephone', '')
或者,简单地说:
entries['extensions'].get('telephone')
get
将返回第二个参数(默认为None
),而不是在找不到密钥时提出KeyError
。
答案 1 :(得分:8)
如果只有一个地方缺少数据,则可以使用dict.get填写错过的缺失值:
tel = d['entries'][0]['extensions'].get('telelphone', '')
如果问题更加普遍,您可以让JSON解析器使用defaultdict或自定义词典而不是常规词典。例如,给定JSON字符串:
json_txt = '''{
"entries": [
{
"extensions": {
"telephone": "123123",
"url": "www.blablablah",
"name": "name",
"coordinates": "coords",
"address": "address"
},
"summary": "here is the summary"
}
]
}'''
解析它:
>>> class BlankDict(dict):
def __missing__(self, key):
return ''
>>> d = json.loads(json_txt, object_hook=BlankDict)
>>> d['entries'][0]['summary']
u'here is the summary'
>>> d['entries'][0]['extensions']['color']
''
作为旁注,如果您想清理数据集并强制执行一致性,那么有一个名为Kwalify的精美工具可以对JSON(和YAML)进行模式验证;
答案 2 :(得分:0)
您可以使用几种有用的字典功能来处理此问题。
首先,您可以使用in
来测试字典中是否存在密钥:
if 'telephone' in entrie['extensions']:
tel=entrie['extensions']['telephone']
get
也可能有用;它允许您在缺少密钥时指定默认值:
tel=entrie['extensions'].get('telephone', '')
除此之外,您可以查看标准库的collections.defaultdict
,但这可能有点过分。
答案 3 :(得分:0)
两种方式。
一个是确保您的词典是标准的,当您阅读它们时,它们具有所有字段。另一个是访问词典时要小心。
以下是确保您的词典符合标准的示例:
__reference_extensions = {
# fill in with all standard keys
# use some default value to go with each key
"coordinates" : '',
"address" : '',
"name" : '',
"telephone" : '',
"url" : ''
}
entrie = json.loads(input_string)
d = entrie["extensions"]
for key, value in __reference_extensions:
if key not in d:
d[key] = value
以下是访问词典时要小心的示例:
for entrie in entries:
name = entrie['extensions'].get('name', '')
tel = entrie['extensions'].get('telephone', '')