新手区 测试工具构建过程中字典列表多层嵌套取值

LEFT · June 14, 2018 · Last by HazeMaker replied at January 21, 2019 · 1702 hits

最近一段时间,公司在着手开发一些测试相关工具,个人参与过程中遇到了字典列表多层嵌套的取值问题,关于此问题的解决方案,自己的一些拙见,敬请指正。

# 获取字典中的objkey对应的值,适用于字典列表嵌套
# test:字典
# objkey:目标key
# default:找不到时返回的默认值
# tmp_list:数据存储列表
# 字典遍历,遍历数据是字典,自执行,是列表执行列表
# 列表遍历,遍历数据是列表,自执行,是字典执行字典
#key值唯一
def list_get(test,objkey,default,tmp_list):
for i in test:
if isinstance(i,dict):
dict_get(i,objkey,default,tmp_list)
elif isinstance(i,list):
list_get(i,objkey,default,tmp_list)

def dict_get(test,objkey,default,tmp_list):
for k,v in test.items():
if k != objkey:
if isinstance(v,dict):
dict_get(v,objkey,default,tmp_list)
elif isinstance(v,list):
list_get(v,objkey,default,tmp_list)
else:
k == objkey
tmp_list.append(v)
return tmp_list[0]
#test:字典
#objkey:目标key
#objupkey:目标上级key
#key值重复,筛选指定key
def list_get(test, objkey,objupkey, default, tmp_list):
for i in test:
if isinstance(i, dict):
dict_get(i, objkey,objupkey, default, tmp_list)
elif isinstance(i, list):
list_get(i, objkey,objupkey, default, tmp_list)


def dict_get(test, objkey,objupkey, default, tmp_list):
for k, v in test.items():
if k != objupkey :
if isinstance(v, dict):
dict_get(v, objkey,objupkey, default, tmp_list)
elif isinstance(v, list):
list_get(v, objkey,objupkey, default, tmp_list)
elif k == objupkey :
if isinstance(v, list):
for e in v:
if isinstance(e, dict):
for u,w in e.items():
if u == objkey:
if w != None:
tmp_list.append(w)
elif isinstance(v, dict):
for u, w in v.items():
if u == objkey:
if w != None:
tmp_list.append(w)
return tmp_list
共收到 8 条回复 时间 点赞

定义一个词法解析规则,比如“person.0.name.alias”,然后 split 后,再遍历解析,参考 httprunner

https://github.com/HttpRunner/HttpRunner/blob/master/httprunner/utils.py#L173:5

LEFT #2 · June 14, 2018 作者
chu 回复

好的🙏,去参考学习一下

定义一个词法解析规则,比如“person.0.name.alias”,然后 split 后,再遍历解析,参考 httprunner

这种访问形式,python的话有现成的库 addict 传送门

LEFT #4 · June 14, 2018 作者
chen 回复

我在一个帖子里看到了你的回复,准备尝试,正在看addict的源码

LEFT 回复

👍 好学!

目前我也在做类似的内容,字典和列表互相嵌套,想直接作对比,看两者是否是包含关系。主要参考了你的代码,但觉得自己写的内容,过于繁琐,想了解下你后续的探索。

代码如下:

def compare_json(responce_data, check_data):
if isinstance(responce_data, dict) and isinstance(check_data, dict):
compare_json = compare_dict(responce_data, check_data)
elif isinstance(responce_data, list) and isinstance(check_data, list):
compare_json = compare_list(responce_data, check_data)
else:
compare_json = False
print "Please check responce_data: %s, check_data: %s. They are not dict or list." % (responce_data, check_data)
return compare_json
if compare_json:
print "responce_data: %s\ncheck_data: %s\nCheck Success!" % (responce_data, check_data)
else:
print "responce_data: %s\ncheck_data: %s\nCheck Fail!" % (responce_data, check_data)

def compare_dict(all_dict, check_dict):
global compare_dict_status
for (check_key, check_value) in check_dict.items():
for (all_key, all_value) in all_dict.items():
compare_dict_status = False
if operator.eq(check_key, all_key):
if isinstance(check_value, dict) and isinstance(all_value, dict):
#print "Dict::Dict check_value is %s, all_value is %s" % (check_value, all_value)
compare_dict_status = compare_dict(all_value, check_value)
if compare_dict_status:
break
elif isinstance(check_value, list) and isinstance(all_value, list):
#print "List::List check_item is %s, all_item is %s" % (check_value, all_value)
compare_dict_status = compare_list(all_value, check_value)
if compare_dict_status:
break
else:
if operator.eq(check_value, all_value):
print "%s:%s is in the %s" % (check_key, check_value, all_dict)
compare_dict_status = True
break
if not compare_dict_status:
print "Can't find %s:%s in the %s" % (check_key, check_value, all_dict)
return compare_dict_status
return compare_dict_status

def compare_list(all_list, check_list):
global compare_list_status
for check_item in check_list:
for all_item in all_list:
compare_list_status = False
if isinstance(check_item, list) and isinstance(all_item, list):
compare_list_status = compare_list(all_item, check_item)
#print "List::List check_item is %s, all_item is %s, compare_list_status is %s" % (check_item, all_item, compare_list_status)
if compare_list_status:
break
elif isinstance(check_item, dict) and isinstance(all_item, dict):
compare_list_status = compare_dict(all_item, check_item)
#print "Dict::Dict check_item is %s, all_item is %s, compare_list_status is %s" % (check_item, all_item, compare_list_status)
if compare_list_status:
break
else:
if operator.eq(check_item, all_item):
print "%s is in the %s" % (check_item, all_list)
compare_list_status = True
break
if not compare_list_status:
print "Can't find %s in the %s" % (check_item, all_list)
return compare_list_status
return compare_list_status
if __name__ == '__main__':
all_list = ["1", "2", "3", "4", "5", {"test1": "1", "test2": "2", "test3": "3", "test9": [{"test6": "6"}, {"test7": "7"}, {"test8": "8"}], "test4": {"x": "9", "y": "0"}, "test5": "5"}]
check_list = ["3", "5", {"test3": "3", "test4": {"y": "0"}, "test9": [{"test7": "7"}]}]
print compare_json(all_list, check_list)
chen 回复

请教一下,这个addict支持python 2的utf-8么?
{'name_1': {u'msg': u'ok', u'code': u'0', u'data': {u'regionPath': u',root000000,c10e92a6-c090-4955-bdab-63eba5965c0a,', u'leaf': True, u'regionStatus': 0, u'dataVersion': 328, u'regionCodeStyle': u'none', u'indexCode': u'c10e92a6-c090-4955-bdab-63eba5965c0a', u'regionId': u'c10e92a6-c090-4955-bdab-63eba5965c0a', u'parentIndexCode': u'root000000', u'regionType': 0, u'regionCode': u'', u'parentId': u'root000000', u'disOrder': 91, u'regionDesc': u'', u'regionName': u'test1'}}}
这样的要如何处理?

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up