【问题标题】:Recursively accessing paths and values of a nested dictionary递归访问嵌套字典的路径和值
【发布时间】:2018-10-08 14:21:55
【问题描述】:

在 Python 2.7 中,如何动态访问和打印嵌套字典的键和值?这是一个荒谬的例子:https://jsoneditoronline.org/?id=da7a486dc2e24bf8b94add9f04c71b4d

通常,我会这样做:

import json

json_sample = 'sample_dict.json'
json_file = open(json_sample, 'r')
json_data = json.load(json_file)

items = json_data['sample_dict']

for item in items:
    dict_id = item['dict_id']
    person = item['person']['person_id']
    family = item['family']['members']

    print dict_id
    print person
    print family

我可以像这样对其进行硬编码,它会给我带来理想的结果,但是我将如何动态访问每个键和值,以便:

  • 第一行只打印键(dict_idperson['person_id']person['name']family['members']['father']
  • 第二行分别打印值(5、15、“Martin”、“Jose”)

最终结果应保存在 CSV 文件中。

【问题讨论】:

  • 你知道 JSON 数据是一个字典列表吗?如果是这样,您可以使用 item.keys() 作为键,使用 item.values() 作为值。
  • 哦,是的,所以如果我这样做item.keys(),它只会给我父母自己的听写,不包括孩子听写。 item.values() 然后会给我那些,但它会包括键,当我只想要值时。

标签: python json python-2.7 list dictionary


【解决方案1】:

您可以使用递归访问者/生成器,它返回叶子的所有路径/值对:

def visit_dict(d, path=[]):
    for k, v in d.items():
        if not isinstance(v, dict):
            yield path + [k], v
        else:
            yield from visit_dict(v, path + [k])

(如果使用 Python yield from ... 替换为 appropriate equivalent

获取密钥:

>>> ','.join('/'.join(k) for k, v in visit_dict(json_data['sample_dict'][0]))
'dict_id,person/person_id,person/name,person/age,family/person_id,family/members/father,family/members/mother,family/members/son,family/family_id,items_id,furniture/type,furniture/color,furniture/size,furniture/purchases'

和价值观:

>>> ','.join(str(v) for k, v in visit_dict(json_data['sample_dict'][0]))
'5,15,Martin,18,20,Jose,Maddie,Jerry,2,None,Chair,Brown,Large,[]'

【讨论】:

  • 哦,这是一个更好的解决方案!但现在我想知道,有没有办法遍历 sample_dict 列表的整个字典中的每个字典(dict_listpurchases)?除了硬编码json_data['sample_dict'][0],有没有办法使[0] 部分动态化,以便在每一行中也产生其余的字典?
  • 是的,for 循环
  • 明确:for d in json_data['sample_dict']: csv_file.write(','.join(str(v) for k, v in visit_dict(d)))
  • 是的!最初,我做了for key in json_data['sample_dict']: csv_file.write(','.join('/'.join(k) for k, v in visit_dict(json_data['sample_dict'][key]))),只是意识到我错误地迭代了它,它只是...visit_dict(key)))。但是,我确实有重复的键,但现在这是一个不同的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-30
  • 2015-09-11
  • 1970-01-01
相关资源
最近更新 更多