python嵌套字典中, 通过key值获取所有的对应的value值的相关处理

有时候面对一些需要处理的数据, 会是一种字典中嵌套字典的数据, 然后里面可能有多个key相同的value都是需要获取的, 比如json中的部分值.

这种直接获取比较困难, 只能自己写一个函数解决

1. 单纯字典的嵌套

下面的大概思路是迭代当前dict的所有元素, 对元素挨个依次比较key与所需要的key, 如果相同就保存在输出的list中.
然后如果遇到value是属于又一个dict, 则进行一个回归, 再次对这个子dict进行相同操作. 最后循环结束后输出list


然后还有可能有些我们搜索的key对应的value的类型有很多, 比如有可能是str的‘abc’, 也有可能是int的123, 也有可能是dict的{‘1’: 123}还有可能是list的[1, 2, 3], tuple的(1, 2, 3). 所以可以设计一个参数来判断是否获取类型为list, dict, tuple的目标值.

# in_dict:需要处理的字典, target_key:目标键
# value:输出的列表,元素为目标键值对应的值(必须为空列表), not_ldt:获取的目标类型不为dict

dicts = {'1': 1, '2': 2, '3': 3, '4': {'5': 55, '6': 66, '7': 77}, '7': {'7': 777}}

def get_dict_value(in_dict, target_key, results=[], not_d=True):
    for key in in_dict.keys():  # 迭代当前的字典层级
        data = in_dict[key]  # 将当前字典层级的第一个元素的值赋值给data
        
		# 如果当前data属于dict类型, 进行回归
        if isinstance(data, dict):
            get_dict_value(data, target_key, results=results, not_d=not_d)
            
		# 如果当前键与目标键相等, 并且判断是否要筛选
        if key == target_key and isinstance(data, dict) != not_d:
            results.append(in_dict[key])

    return results

上面的函数可以实现单纯的对嵌套字典的回归查找.
比如:

  1. 默认:
# 获取dicts中所有key为‘7’的value, 并且默认的不获取类型为dict的value.
a = get_dict_value(dicts, '7', results=[])
print(a)

输出:

[77, 777]
  1. 修改not_ldt参数:
# 获取dicts中所有key为‘7’的value, 并且获取类型为dict的value.
a = get_dict_value(dicts, '7', results=[], not_d=False)
print(a)

输出:

[77, 777, {'7': 777}]
  1. 注意⚠️: 有个问题就是, 如果要对函数调用两次, 因为value值在第一次调用的时候没有清空, 所以第二次调用的时候会出现第一次的结果. 解决办法就是每次调用的时候添加value=[]参数清空value值.
# 当调用连续两次函数的时候, 不对results进行初始化的时候:
a = get_dict_value(dicts, '7')
b = get_dict_value(dicts, '7')
print(b)

输出:

[77, 777, 77, 777]

可见每次调用的时候最好使用value=[]初始化一下. 这个问题暂时没有想出好方法解决, 如果有更好的方法, 欢迎大家评论指出咯.

2. 字典,列表,元组的多类型嵌套

上面那个默认的字典里面元素的值要么是字符, 数字, 或者就是字典类型的, 所以在if判断的时候只有一个判断是否为dict类型的, 但是实际上, 对于要处理json数据的时候, 里面的字典的元素可能是list, tuple之类的, 比如:{‘1’: 1, 2: [{‘33’: 33}, (44, 55, 66)]}这种类型的内部元素比较复杂的json.

下面对上面的函数进行更新, 以期望实现更加具有通用性的功能, 毕竟遇见复杂的类型的json数据的情况更加多一点.

# in_json:需要处理的json数据, target_key:目标键
# value:输出的列表,元素为目标键值对应的值(必须为空列表)

dd = {'a': 'ok1', '1': {'1': 11, '2': ('a', 111, {'a': 'ok2'}, [{'a': 'ok3'}, 2222], {'a': [11111, 22222]})}, '2': '2'}  # json数据例子

def get_json_value_by_key(in_json, target_key, results=[]):
    if isinstance(in_json, dict):  # 如果输入数据的格式为dict
        for key in in_json.keys():  # 循环获取key
            data = in_json[key]
            get_json_value_by_key(data, target_key, results=results)  # 回归当前key对于的value

            if key == target_key:  # 如果当前key与目标key相同就将当前key的value添加到输出列表
                results.append(data)

    elif isinstance(in_json, list) or isinstance(in_json, tuple):  # 如果输入数据格式为list或者tuple
        for data in in_json:  # 循环当前列表
            get_json_value_by_key(data, target_key, results=results)  # 回归列表的当前的元素

    return results

上面的函数便可以实现, 更加复杂的嵌套有列表, 元组的字典的查找.
比如:

  1. 默认:
# 当调用连续两次函数的时候, 不对results进行初始化的时候:
 = get_dict_value(dd, 'a')
print(a)

输出:

['ok1', 'ok2', 'ok3', [11111, 22222]]

这个函数依然存在连续多次调用时, 需要初始化的不然会包含前面的结果的问题.

  • 17
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值