编写Python来处理JSON数组的不一致性

时间:2018-03-08 22:50:00

标签: python arrays json api jagged-arrays

我一直在玩Python抓取和解析来自JSON API的数据。具体来说,我正在与CTA(芝加哥交通管理局)Train Tracker API合作。

我定期收到一个TypeError: string indices must be integers,我跟踪到的是一个多次“列车”运行的阵列,而不是单个“列车”运行。单次运行不在运行数组中。

{'ctatt':
 {'tmst': '2018-03-05T01:59:10',
 'errCd': '0',
 'errNm': None,
 'route': [{'@name': 'g'},
           {'@name': 'y',
            'train': {'rn': '030',
                     .....
                      'heading': '302'},
           {'@name': 'blue',
            'train': [{'rn': '125',
                     .....
                       'heading': '302'},
                      {'rn': '127',
                     ..... 
                       'heading': '278'},

'g'路线没有跑步的实例。 'y'路线有1次运行。

  'train': {'rn':}

'blue'路线有多次运行。

  'train': [{'rn': ...},{'rn': ...},{'rn': ...}]

我用来解析的代码处理缺少运行和多次运行。它以1次运行命中TypeError

for train_rt in trains_data['ctatt']['route']:
    line_name = train_rt['@name']
    if train_rt.get('train', 'None') != 'None':
        for train_run in train_rt['train']:

处理不在数组中的单次运行的最佳方法是什么?

2 Yellow Line Runs in Chrome: Dev Tools: Network: Preview

1 Yellow Line Run in Chrome: Dev Tools: Network: Preview

我注意到的一个不一致是,如果我查询单个路由,路由仍然是1路由的数组。

1 个答案:

答案 0 :(得分:3)

您有两种选择:

  • 使用isinstance()
  • 显式测试列表或字典
  • 将您的访问权限置于try:...except并抓住TypeError,然后继续将其视为单个元素。

你选择哪一个(但有can be a performance difference)并不重要,选择你觉得最适合你代码的风格。

例如,如果您使用isistance()测试,则可以在单个元素周围添加列表,以便其余代码不必更改:

for train_rt in trains_data['ctatt']['route']:
    line_name = train_rt['@name']

    train_runs = train_rt.get('train', [])
    if not isinstance(train_runs, list):
        # single entry, wrap
        train_runs = [train_runs]

    for train_run in train_runs:
        # ...

请注意,如果缺少'train'密钥,则上述代码将再次使用空列表进行规范化。这允许您避免另一个if测试,因为现在for循环根本不会迭代。

如果您有该API的支持联系人,我至少会报告该问题,并指出他们的数据结构不一致。