2013-05-10 80 views
8

我在使用python解析JSON时遇到问题,现在我卡住了。
问题是我的JSON的实体并不总是相同的。 JSON的是一样的东西:使用python解析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'] 

但我认为不好。

回答

11

使用dict.get而不是[]

entries['extensions'].get('telephone', '') 

或者,干脆:

entries['extensions'].get('telephone') 

get将返回第二个参数(默认情况下,None),而不是养KeyError时找不到键。

0

有几个有用的字典功能,你可以用它来处理这个。

首先,你可以使用in测试在字典中是否存在的关键:

if 'telephone' in entrie['extensions']: 
    tel=entrie['extensions']['telephone'] 

get也可能是有用的;它可以让你如果密钥丢失指定一个默认值:

tel=entrie['extensions'].get('telephone', '') 

除此之外,你可以看看标准库的collections.defaultdict,但可能是矫枉过正。

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'] 
'' 

作为一个侧面说明,如果你想清理你的数据集和执行的一致性,有一个叫精细的工具对JSON(和YAML)进行模式验证的Kwalify;

+1

不错,我很喜欢这更好然后'defaultdict '因为'__missing__'方法中可以添加一些逻辑来捕捉潜在的错误。使用'defaultdict'时,我总是畏缩,因为当我输错时我不会得到KeyError。 – 2013-05-11 00:18:03

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