编码 Python 以处理 JSON 数组不一致
Coding Python to handle JSON array inconsistencies
我一直在玩 Python 从 JSON API 抓取和解析数据。具体来说,我正在与 CTA(芝加哥交通管理局)Train Tracker API 合作。
我定期收到一个 TypeError: string indices must be integers
,当多个 'train' 运行 的数组与单个 'train' 运行 存在时,我追踪到 a .单个 运行 不在 运行 的数组中。
{'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 个路由的数组中。
您有两个选择:
- 使用
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,我至少会报告该问题并指出他们的数据结构不一致。
我一直在玩 Python 从 JSON API 抓取和解析数据。具体来说,我正在与 CTA(芝加哥交通管理局)Train Tracker API 合作。
我定期收到一个 TypeError: string indices must be integers
,当多个 'train' 运行 的数组与单个 'train' 运行 存在时,我追踪到 a .单个 运行 不在 运行 的数组中。
{'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 个路由的数组中。
您有两个选择:
- 使用
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,我至少会报告该问题并指出他们的数据结构不一致。