一、问题背景
在做接口自动化的过程中,接口返回的数据是 列表字典循环嵌套 格式的,所以怎样通过一个key值,获取到被包裹了多层的目标数据成为了摆在我面前的一个问题。
解决思路
最初的做法是写一个函数,每次对传入的数据进行类型判断,然后根据数据类型做对应的处理,后来发现如果这样,实际有多少层数据就要做多少次判断。
调试过程中发现,函数的调用特别符合递归的规律,但是和一般递归的略有不同,需要两个函数相互调用递归。实测可以完美解决这个问题!
具体思路如下:
新建两个函数A和B,函数 A处理字典数据,被调用后,判断传递的参数,如果参数为字典,则调用自身;
如果是列表或者元组,则调用列表处理函数B;
函数 B处理列表,被调用后,判断传递的参数,如果参数为列表或者元组,则调用自身;
如果是字典,则调用字典处理函数A;
def get_target_varlue(key, dic, tmp_list):
"""
:param key: 目标key值
:param dic: JSON数据
:param tmp_list: 用于存储获取的数据
:return: list
"""
if not isinstance(dic, dict) or not isinstance(tmp_list, list): # 对传入数据进行格式校验
return 'argv[1] not an dict or argv[-1] not an list '
if key in dic.keys():
tmp_list.append(dic[key]) # 传入数据存在则存入tmp_list
for value in dic.values(): # 传入数据不符合则对其value值进行遍历
if isinstance(value, dict):
get_target_varlue(key, value, tmp_list) # 传入数据的value值是字典,则直接调用自身
elif isinstance(value, (list, tuple)):
__get_value(key, value, tmp_list) # 传入数据的value值是列表或者元组,则调用_get_value
return tmp_list
def __get_value(key, val, tmp_list):
for val_ in val:
if isinstance(val_, dict):
get_target_varlue(key, val_, tmp_list) # 传入数据的value值是字典,则调用get_target_value
elif isinstance(val_, (list, tuple)):
__get_value(key, val_, tmp_list) # 传入数据的value值是列表或者元组,则调用自身
if __name__== '__main__':
dic = {'a': '1', 'b': '2',
'c': {'d': [{'e': [{'f': [{'v': [{'g': '6'}, [{'g': '7'}, [{'g': 8}]]]}, 'm']}]}, 'h', {'g': [10, 12]}]}}
print('a 的值为:', get_target_varlue('a', dic, []))
print('v 的值为:', get_target_varlue('v', dic, []))
print('g 的值为:', get_target_varlue('g', dic, []))
print('h 的值为:', get_target_varlue('h', dic, []))
print('d 的值为:', get_target_varlue('d', dic, []))
二、字典键值的调用方法
dict = {}
dict['one'] = "This is one"
dict[2] = "This is two"
tinydict = {'name': 'runoob','code':6734, 'dept': 'sales'}
print dict['one'] # 输出键为'one' 的值
print dict[2] # 输出键为 2 的值
print tinydict # 输出完整的字典
print tinydict.keys() # 输出所有键
print tinydict.values() # 输出所有值