繁体   English   中英

在Python中的嵌套JSON对象中返回值

[英]Returning values in nested JSON objects in Python

首先,我要说这个问题有两个部分,第二部分最后提到。

我想获取具有特定名称的所有关联字符串的值。 让我尝试用一​​些示例JSON进行解释。

{
  "data": {
    "list": {
      "123": {
        "location": 123,
        "x": 0.1,
        "y": 0.2,
        "ids": [
          {
            "id_a": 123
            "id_b": 442
          },
          {
            "id_a": 123
            "id_b": 443
          },
          {
            "id_a": 123
            "id_b": 444
          }
        ]
      }
      "555": {
        "location": 555,
        "x": 0.6,
        "y": 0.4,
        "ids": [
          {
            "id_a": 555
            "id_b": 449
          },
          {
            "id_a": 555
            "id_b": 450
          }
        ]
      }
    }
  }
}

我想返回所有“ id_b”值的数组。 这是我想要的输出:

array = [442, 443, 444, 449, 450]

我最近的是通过使用以下内容:

import json
import urllib.request as ur

file = ur.urlopen(url)
data = json.loads(file.read())

r = []
r = data['data']['list']['123']['ids'][0]['id_b']
print(r)

在这里我将得到442。删除[0]会留下“ TypeError:列表索引必须是整数或切片,而不是str”。 我可以尝试并包含一个循环,其中[0]变为[i],而i是'ids'的数量,但此数字并非在所有位置都一致。

我还没有找到像这样的JSON结构使用Python的任何示例。 如果有人知道有什么资源可以帮助我,我会很高兴地从这些资源开始。

另外,有问题的网址每天都会更改,我有相应的代码可以根据日期更改网址。 但是,当更改日期时,“列表”下的对象名称也会更改,即“ 123”可能变为“ 326”。 同样与“位置”和“ id_a”。 这些都是一样的。 “ 123” =“位置”值=“ id_a”值。

有没有一种方法可以将所有带有字符串“ id_b”的值简单地放入数组中? 最终这就是我想要的。

您可以尝试递归方法:

def find_by_key(obj, key):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if k == key:
                yield v

            else:
                yield from find_by_key(v, key)

    elif isinstance(obj, list):
        for sub in obj:
            yield from find_by_key(sub, key)

    else:
        return

print(list(find_by_key(data, 'id_b')))

输出:

[442, 443, 444, 449, 450]

您需要递归函数

递归函数:

递归是对问题进行编程或编码的一种方法,其中函数在自身体内对其进行一次或多次调用。 通常,它返回此函数调用的返回值。

终止条件:递归函数必须终止才能在程序中使用。 如果每次进行递归调用时问题的解决方案减小了尺寸,并朝着基本情况发展,则递归函数终止。 基本情况是无需进一步递归即可解决问题的情况。

def id_generator(dict_var, key):
    for k, v in dict_var.items():
        if isinstance(v, dict):
            for id_val in id_generator(v,key):
                yield id_val
        elif isinstance(v, list):
            for item in v:
                yield item[key]

key = 'id_b'
print(list(id_generator(data, key)))

输出:

[442, 443, 444, 449, 450]

假设没有比示例中显示的嵌套更多的嵌套,则可以使用单个列表推导:

>>> d = json.load(open("tmp.json"))
>>> [i['id_b'] for v in d['data']['list'].values()
...            for i in v['ids']]
[442, 443, 444, 449, 450]

如果顺序很重要(尽管不应该这样 ,因为JSON对象中的键顺序是未定义的),那么您必须依靠python 3.7保证的dicts迭代顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM