使用python解析JSON:空白字段

时间:2013-05-10 23:45:27

标签: python json parsing python-2.7

我在使用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']

但我认为不行。

4 个答案:

答案 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', '')