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

Iterating though a relatively consistent JSON file using try statements in Python

我有一个关于使用 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),偶尔会缺少一对 key/value。

如果缺少一个或两个或 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"

感谢任何建议!

您也可以遍历键名 - 这意味着您只有 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]

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

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

which returns 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 中的 中的键,仅此而已。

这是我用来遍历 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