栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

帮助理解json(dict)结构的函数

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

帮助理解json(dict)结构的函数

这是一组递归生成器,可用于搜索由字典和列表组成的对象。

find_key
产生一个元组,其中包含字典键列表和导致您传入的键的列表索引;元组还包含与该键关联的值。因为它是一个生成器,所以如果需要的话,如果对象包含多个匹配键,它将找到所有匹配键。

def find_key(obj, key):    if isinstance(obj, dict):        yield from iter_dict(obj, key, [])    elif isinstance(obj, list):        yield from iter_list(obj, key, [])def iter_dict(d, key, indices):    for k, v in d.items():        if k == key: yield indices + [k], v        if isinstance(v, dict): yield from iter_dict(v, key, indices + [k])        elif isinstance(v, list): yield from iter_list(v, key, indices + [k])def iter_list(seq, key, indices):    for k, v in enumerate(seq):        if isinstance(v, dict): yield from iter_dict(v, key, indices + [k])        elif isinstance(v, list): yield from iter_list(v, key, indices + [k])# testdata = {    '1_data': {        '4_data': [ {'5_data': 'hooray'}, {'3_data': 'hooray2'}        ],         '2_data': []    }}for t in find_key(data, '3_data'):    print(t)

输出

(['1_data', '4_data', 1, '3_data'], 'hooray2')

要获取单个键列表,可以传递

find_key
给该
next
函数。如果要使用键列表来获取关联的值,则可以使用简单的
for
循环。

seq, val = next(find_key(data, '3_data'))print('seq:', seq, 'val:', val)obj = datafor k in seq:    obj = obj[k]print('obj:', obj, obj == val)

输出

seq: ['1_data', '4_data', 1, '3_data'] val: hooray2obj: hooray2 True

如果密钥可能丢失,请提供

next
适当的默认元组。例如:

seq, val = next(find_key(data, '6_data'), ([], None))print('seq:', seq, 'val:', val)if seq:    obj = data    for k in seq:        obj = obj[k]    print('obj:', obj, obj == val)

输出

seq: [] val: None

请注意,此代码是针对Python 3的。要在Python 2上运行,您需要替换所有

yield from
语句,例如replace

yield from iter_dict(obj, key, [])

for u in iter_dict(obj, key, []):    yield u

这个怎么运作

要了解此代码的工作原理,您需要熟悉递归和Python生成器。您可能还会发现此页面有帮助:了解Python中的生成器;在线上也有各种Python生成器教程。

json.load
或返回的Python对象
json.loads
通常是字典,但也可以是列表。我们将该对象
find_key
作为
obj
arg传递给生成器,并附带
key
我们要查找的字符串。
find_key
然后根据需要调用
iter_dict
iter_list
,将它们,对象,键和一个空列表传递给它们,该空列表
indices
用于收集dict键和列出指向所需键的索引。

iter_dict
在其
d
dict
arg的顶层迭代每个(k,v)对。如果
k
与我们要查找的键匹配,则会生成当前
indices
列表
k
并附加到当前列表以及相关的值。因为
iter_dict
是递归的,所以产生的(索引列表,值)对将传递到递归的上一级别,最终使其到达
find_key
并到达调用的代码
find_key
。请注意,这是递归的“基本情况”:这是确定此递归路径是否指向所需键的代码的一部分。如果递归路径从没有找到与我们要查找的键匹配的键,则该递归路径将不会添加任何内容,
indices
并且它将终止而不产生任何结果。

如果当前

v
是字典,那么我们需要检查它包含的所有(键,值)对。我们通过对进行递归调用来实现
iter_dict
,将
v
其作为起始对象和当前
indices
列表进行传递。如果当前
v
是一个列表,我们改为调用
iter_list
,将相同的参数传递给它。

iter_list``iter_dict
除了列表没有任何键,它只包含值之外,其工作方式与之类似。因此,我们不执行
k ==key
测试,而是递归到原始列表包含的所有字典或列表。

该过程的最终结果是,当我们进行迭代时,

find_key
我们得到(索引,值)对,其中每个
indices
列表是dict键的序列和列表索引,这些索引成功地终止于带有所需键的dict项中,并且
value
是关联的值用那个特定的钥匙。

如果您想查看此代码的其他示例,请参阅如何修改嵌套Json的键以及如何从python的字典中选择深度嵌套的key:values。

还要看看我的新的,更简化的

show_indices
功能。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/441219.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号