使用Python中的try语句遍历相对一致的JSON文件

时间:2018-10-27 13:43:28

标签: python json try-except

我有一个最佳实践问题,涉及使用try / except语句遍历Python中的JSON文件。

我有一个看起来像这样的JSON文件(此问题大大简化了):

"results": [
      {
       "listingId":"1"
       "address":"123 Main st"
       "landsize":"190 m2"
      },
      {
       "listingId":"2"
       "address":"345 North st"
       "state":"California"
      }
  ]

正如我所说,这是超级简化的(在我的实际问题中,我感兴趣的大约有30个键值对,并且有成千上万条记录)面临的挑战是,即使键非常一致(始终存在)相同的30),偶尔会有缺失的键/值对。

如果缺少一两个或10个,我希望将其余记录写出,所以目前的方法是对每个键值对使用try / catch语句,这似乎使我很惊讶一种非常低效的检查方法,我相信还有更好的方法。

我的代码看起来像这样(我确信这不是执行此操作的最佳方法):

for i in range(len(JSON_data["results"])):
   try:
      print "ListingID=" + JSON_data["results"][i]["listingId"]
   except KeyError:
      print "ListingID is unknown"

   try:
      print "Address=" + JSON_data["results"][i]["address"]
   except KeyError:
      print "Address is unknown"

   try:
      print "landsize=" + JSON_data["results"][i]["landsize"]
   except KeyError:
      print "landsize is unknown"

   try:
      print "state =" + JSON_data["results"][i]["state"]
   except KeyError:
      print "state is unknown"

任何建议表示赞赏!

3 个答案:

答案 0 :(得分:2)

您可以使用dict.get() method避免捕获异常:

listing_id = JSON_data["results"][i].get("listingId")

返回None或其他默认值,作为第二个参数传入。您还可以检查密钥是否先出现:

if 'listingId' in JSON_data["results"][i]:
    # the key is present, do something with the value

接下来,您要在此处不使用range() 。您最好直接在results列表上循环,因此每次都可以直接引用字典而无需使用完整的JSON_data["results"][i]前缀:

for nesteddict in JSON_data["results"]:
    if 'listingId' in nesteddict:
        listing_id = nesteddict['nesteddict']

接下来,而不是对您检查的所有键进行硬编码,请在键列表上使用循环:

expected_keys = ['listingId', 'address', 'landsize', ...]

for nesteddict in JSON_data["results"]:
    for key in expected_keys:
        if key not in nesteddict:
            print(key, 'is unknown')
        else:
            value = nesteddict[key]
            print('{} = {}'.format(key, value)

如果不需要打印缺少的键,则还可以使用dictionary views,它是一组键。设置支持交集操作,因此您可以要求您期望的键和可用键之间的交集:

# note, using a set here now
expected_keys = {'listingId', 'address', 'landsize', ...}

for nesteddict in JSON_data["results"]:
    for key in nesteddict.keys() & expected_keys:  # get the intersection
        # each key is guaranteed to be in nesteddict
        value = nesteddict[key]
        print('{} = {}'.format(

for循环仅处理nesteddict中的expected_keys中的键,仅此而已。

答案 1 :(得分:1)

您也可以遍历键名-这意味着您只有1个try / except。由于它是循环的,因此它会为每个键重复相同的代码,并在每个循环中更改键名称。

for i in range(len(JSON_data["results"])):
    for key in ('listingId', 'address', 'landsize', 'state'):
        try:
            print '{}: {}'.format(key, JSON_data["results"][i][key])
        except KeyError:
            print '{} is unknown'.format(key)

如果我没记错的话,您还可以通过直接遍历结果来使代码更简洁:

for result in JSON_data['results']:
    ...

在编写JSON_data['results'][i]的地方,将其更改为简单的result

注意:您提到的实际数据要比这复杂得多。如果密钥名称很多,则可以在外部(或至少在其他位置)存储密钥名称。您可以通过执行以下操作来创建键名称文件并创建名称列表:

with open('key_names.txt', 'r') as f:
    key_names = [line.strip() for line in f]

答案 2 :(得分:0)

这是我用于遍历json对象并列出所需值的方法。另外,在发布到这里之前,请确保您正确设置了json对象的格式。

import json


def import_data():
    data = """
    {
"results": [
      {
       "listingId":"1",
       "address":"123 Main st",
       "landsize":"190 m2"
      },
      {
       "listingId":"2",
       "address":"345 North st",
       "state":"California"
      }
  ]
}
"""
    return data

def format_Data():
    data = import_data()
    data = json.loads(data)
    array = []
    print data
    for data_item in data['results']:
        for key, value in data_item.items():
            if key == 'listingId':
                listingId = value
                print ('ListingID= {}').format(listingId)
            elif key == 'address':
                address = value
                print ('Address= {}').format(address)
            elif key == 'landsize':
                landsize = value
                print ('Landsize= {}').format(landsize)
            elif key == 'state':
                state = value
                print ('State= {}').format(state)

输出:

{u'results': [{u'landsize': u'190 m2', u'listingId': u'1', u'address': u'123 Main st'}, {u'state': u'California', u'listingId': u'2', u'address': u'345 North st'}]}
Landsize= 190 m2
ListingID= 1
Address= 123 Main st
State= California
ListingID= 2
Address= 345 North s

t