Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当我从一个可能包含一个dict列表但可能不包含的字典中读取时,如何使用for循环?_Python_Json - Fatal编程技术网

Python 当我从一个可能包含一个dict列表但可能不包含的字典中读取时,如何使用for循环?

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

我提前向你道歉,这个标题太让人困惑了。它在代码中更有意义,因此:

我正在解析一个返回JSON的REST API中的数据,这个特殊结构有点问题:

{ '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
现在是一个包含字典的字符串,而不是列表中的字典。几个小时以来,我一直在为这个问题绞尽脑汁,我觉得我错过了一些显而易见的东西

以下是我尝试过的一些事情:

  • 使用
    len(line)
    查看它是否为单行订单提供了一些独特的功能。事实并非如此。它返回字典中key:value对的数量,在我的实际程序中是10,包含10行的顺序也会返回
  • 使用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的开发人员进行调试,看看他们是否可以返回更一致的数据结构!