Python 当我从一个可能包含一个dict列表但可能不包含的字典中读取时,如何使用for循环?
我提前向你道歉,这个标题太让人困惑了。它在代码中更有意义,因此: 我正在解析一个返回JSON的REST API中的数据,这个特殊结构有点问题:Python 当我从一个可能包含一个dict列表但可能不包含的字典中读取时,如何使用for循环?,python,json,Python,Json,我提前向你道歉,这个标题太让人困惑了。它在代码中更有意义,因此: 我正在解析一个返回JSON的REST API中的数据,这个特殊结构有点问题: { 'Order' : [ { 'orderID': '1', 'OrderLines': { 'OrderLine': [ { 'lineID':'00001', 'quantity':'1', 'cost':'10', 'description':'foo' }, { 'lineID':'000
{ 'Order' : [
{ 'orderID': '1',
'OrderLines': {
'OrderLine': [
{ 'lineID':'00001', 'quantity':'1', 'cost':'10', 'description':'foo' },
{ 'lineID':'00002', 'quantity':'2', 'cost':'23.42', 'description':'bar' }
]}
}
{ 'orderID': '2',
'OrderLines': {
'OrderLine':
{ 'lineID':'00003', 'quantity':'6', 'cost':'12.99', 'description':'lonely' }
}
}
]}
如果您注意到,第二个订单只有一个订单行
,因此它不会返回包含字典的列表,而是返回字典。以下是我试图做的:
orders_json = json.loads(from_server)
for order in orders_json['Order']:
print 'Order ID: {}'.format(order['orderID'])
for line in order['OrderLines']['OrderLine']:
print '-> Line ID: {}, Quantity: {}'.format(line['lineID'], line['quantity'])
对于第一个顺序,它可以正常工作,但是第二个顺序抛出TypeError:string索引必须是整数
,因为line
现在是一个包含字典的字符串,而不是列表中的字典。几个小时以来,我一直在为这个问题绞尽脑汁,我觉得我错过了一些显而易见的东西
以下是我尝试过的一些事情:
- 使用
查看它是否为单行订单提供了一些独特的功能。事实并非如此。它返回字典中key:value对的数量,在我的实际程序中是10,包含10行的顺序也会返回len(line)
- 使用try/except。好吧,这就阻止了打字错误停止了整个过程,但一旦我这么做了,我就不知道如何在字典中寻址了。Line是单行订单的字符串,而不是字典
- 无论是谁设计了该API,都没有做得非常好。无论如何,您可以检查
OrderLine
是否是一个列表,如果不是,则在进行任何处理之前将其包装在一个元素列表中:
if not isinstance(order_line, list):
order_line = [order_line]
那就行了,我个人的偏好是把API修好。不管是谁设计的API都做得不太好。无论如何,您可以检查
OrderLine
是否是一个列表,如果不是,则在进行任何处理之前将其包装在一个元素列表中:
if not isinstance(order_line, list):
order_line = [order_line]
那就行了,我个人的偏好是修复API。您可以检查尝试访问的对象的类型:
# ...
print 'Order ID: {0}'.format(order['orderID'])
lines = order['OrderLines']['OrderLine']
if isinstance(lines, list):
for line in lines:
print line['lineID']
elif isinstance(lines, dict):
print lines['lineID']
else:
raise ValueError('Illegal JSON object')
编辑:按照@NPE的建议,将
dict
包装在列表中
是一个更好、更智能的解决方案。您可以检查尝试访问的对象的类型:
# ...
print 'Order ID: {0}'.format(order['orderID'])
lines = order['OrderLines']['OrderLine']
if isinstance(lines, list):
for line in lines:
print line['lineID']
elif isinstance(lines, dict):
print lines['lineID']
else:
raise ValueError('Illegal JSON object')
编辑:按照@NPE的建议,将
dict
包装在列表中
是更好、更智能的解决方案。我会检查类型是否正确,然后在必要时将其转换为列表,以获得统一的访问权限:
lines = order['OrderLines']['OrderLine']
lines = [lines] if not isinstance(lines, list) else lines
for line in lines:
...
我会检查类型是否正确,然后在必要时将其转换为列表,以实现统一访问:
lines = order['OrderLines']['OrderLine']
lines = [lines] if not isinstance(lines, list) else lines
for line in lines:
...
我选择了康斯坦丁尼乌斯的答案,尽管你们都建议了相同的解决方案,因为它将解决方案放在一行上。我很感激你的回答,我希望我能对API返回数据的方式有更多的影响。我将对API的开发人员进行调试,看看他们是否可以返回更一致的数据结构!我选择了康斯坦丁尼乌斯的答案,尽管你们都建议了相同的解决方案,因为它将解决方案放在一行上。我很感激你的回答,我希望我能对API返回数据的方式有更多的影响。我将对API的开发人员进行调试,看看他们是否可以返回更一致的数据结构!