一、需求描述

写一段代码,要求输入任意一个字典(可有其他参数输入),无论它是什么样的结构,都能通过该段代码获取其取值路径,例如字典:

test_data = {"a":{"b":1},"c":[2,{"d":3}],"e":"success",
}

需要输出:

test_data["a"]["b"]
test_data["c"][0]
test_data["c"][1]["d"]
test_data["e"]

二、方案分析

1、这是一个拆解字典的过程,很容易想到使用遍历dict.items()的方法进行处理

2、字典可包含python所有数据类型,如字典、列表、元组、字符串等等

3、根据需求描述,没有对数据类型进行限制,因此这里只对Json格式数据类型进行处理

4、这里先实现需求的部分功能(后续继续优化),限制数据类型范围为:字典、列表和其他(如字符串、数字等无法拆分的末端值)

5、这里需要对路径进行循环利用,如果一个字典深度很长,那么在循环处理时,就得不断使用for来不断解包,感觉递归更好一些

6、递归的时候,如果一开始解压的是字典,那么当遇到列表的情况,可能就无法递归了

7、感觉这问题没法解决了呀?我相信只要是有逻辑的东西,就一定可以通过代码实现!先动手试试吧!

三、实践过程

1、采用递归方式,同时递归字典或列表:版本1

def get_value_path(data):'''递归一个序列(传入列表或字典),如果列表中的元素不是字典或列表,则输出;如果是列表,则继续递归,直到全部输出非字典或列表的元素'''if isinstance(data, list):for index,value in enumerate(data):get_value_path(value)elif isinstance(data, dict):for key,value in data.items():get_value_path(value)else:yield dataif __name__ == "__main__":test_data = {"a": {"b": 1},"c": [2, {"d": 3}],"e": "success",}for value in get_value_path(test_data):print(value)

(1)实践结果:

最终的输出为空,即没有任何输出

(2)案例分析:

①程序逻辑应该简单明了,即判断传入数据是列表或字典则继续递归,不是则输出

②上述没有输出,是因为假设第一次解压的是字典,第二次解压的是列表,意味着在两个不同的for循环中切换,但程序是顺序执行的,因此在一个循环中就已经遍历了所有,以至于没有输出,过程如下:

(3)思考:

应该需要在for循环中,使用yield继续输出

2、采用递归方式,同时递归字典或列表:版本2

def get_value_path(data):'''递归一个序列(传入列表或字典),如果列表中的元素不是字典或列表,则输出;如果是列表,则继续递归,直到全部输出非字典或列表的元素'''if isinstance(data, list):for index,value in enumerate(data):if isinstance(value, list):get_value_path(value)elif isinstance(value, dict):get_value_path(value)else:yield valueelif isinstance(data, dict):for key,value in data.items():if isinstance(value, list):get_value_path(value)elif isinstance(value, dict):get_value_path(value)else:yield valueelse:yield dataif __name__ == "__main__":test_data = {"a": {"b": 1},"c": [2, {"d": 3}],"e": "success",}for value in get_value_path(test_data):print(value)

(1)实践结果:

只输出了一个值:success

(2)案例分析:

(3)思考:

这是为什么呢?这个程序只对一级包做了处理,没法处理到二级包?整个解包过程确实是对一级包做的处理,因为for循环在这里递归的时候,数据取的就是一级包的数据(即使将value全部更换为data),实验如下:

那要想解包到第二层,该怎么做呢?

3、采用递归方式,同时递归字典或列表:版本3

def get_value_path(data):'''递归一个序列(传入列表或字典),如果列表中的元素不是字典或列表,则输出;如果是列表,则继续递归,直到全部输出非字典或列表的元素'''if isinstance(data, list):for index,data in enumerate(data):if isinstance(data, list):for index, data in enumerate(data):if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield data# get_value_path(data)elif isinstance(data, dict):for key, data in data.items():if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield data# get_value_path(data)else:yield dataelif isinstance(data, dict):for key,data in data.items():if isinstance(data, list):for index, data in enumerate(data):if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield data# get_value_path(data)elif isinstance(data, dict):for key, data in data.items():if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield data# get_value_path(data)else:yield dataelse:yield dataif __name__ == "__main__":test_data = {"a": {"b": 1},"c": [2, {"d": 3}],"e": "success","f": "fail",}for value in get_value_path(test_data):print(value)

(1)实践结果:

采用嵌套的方式,能解到第二层:

(2)案例分析:

这样的方式,从结果看起来可行,但是如果要解包很多层,代码就只剩下复制粘贴了,只是,这样的世界何时是个尽头?

(3)思考:

能否先知道这个字典的深度,再通过生成函数的方式,以eval()或exec()实现整段代码的运行?这样做相当麻烦,但貌似是个可行的思路。

4、采用递归方式,同时递归字典或列表:版本4

min_def = '''
def get_value_path(data):data = dataif isinstance(data, list):for index,data in enumerate(data):if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield dataelif isinstance(data, dict):for key,data in data.items():if isinstance(data, list):get_value_path(data)elif isinstance(data, dict):get_value_path(data)else:yield dataelse:yield datatest_data = {"a": {"b": 1},"c": [2, {"d": 3}],"e": "success","f": "fail",
}
for value in get_value_path(test_data):print(value)
'''if __name__ == "__main__":exec(min_def)

(1)实践结果:

(2)案例分析:

通过这种方式是可以运行的,接下来就是对min_def参数化,以达到想要的结果。

(3)思考:

可能需要解决的问题有:python代码格式化问题(空格)、参数化问题、插入代码片段问题等等。

5、采用递归方式,同时递归字典或列表:版本5

# 数据格式:
# 替换单元1
replace_list='''
for index, data in enumerate(data):if isinstance(data, list):{list}elif isinstance(data, dict):{dict}else:yield data
'''
# 替换单元2:
replace_dict='''
for key,data in data.items():if isinstance(data, list):{list}elif isinstance(data, dict):{dict}else:yield data
'''
# 替换单元3:
replace_end = '''
get_value_path(data)
'''
# 最小单元:
min_def = '''
def get_value_path(data):data = dataif isinstance(data, list):for index,data in enumerate(data):if isinstance(data, list):{list}elif isinstance(data, dict):{dict}else:yield dataelif isinstance(data, dict):for key,data in data.items():if isinstance(data, list):{list}elif isinstance(data, dict):{dict}else:yield dataelse:yield datafor value in get_value_path(test_data):print(value)
'''def add_spaces(str_src, n=0):line = str_src.splitlines()for index, l in enumerate(line):line[index] = " "*n + line[index]str_add = "\n".join(line)return str_adddef base_point(str_src):line = str_src.splitlines()point = ""for index, l in enumerate(line):if "{list}" in l:point = l.find("{list}")breakreturn point# n为dict的层数
def main(data,n=10):# 变量test_data固定不变,因为min_def中会使用test_data = data# min_def的最终函数字符串min_def_get = min_deffor i in range(n):if i == n-1:p = base_point(min_def_get)str_a = str_b = add_spaces(replace_end, n=p)def_add = min_def_get.format(list=str_a, dict=str_b)min_def_get = def_addelse:p = base_point(min_def_get)str_a = add_spaces(replace_list, n=p)str_b = add_spaces(replace_dict, n=p)def_add = min_def_get.format(list=str_a, dict=str_b)min_def_get = def_add# print(min_def_get)exec(min_def_get)if __name__ == "__main__":test_data01 = {"a": {"b": 1},"c": [2, {"d": 3},[4,5,6,7,8,9]],"e": "success","f": "fail",}main(test_data01)

(1)实践结果:

已经能够获取最终值!

(2)案例分析:

能够通过该方式获取到指定值,说明也能够通过其获取其路径。

(3)思考:

如何获取路径呢?每一次递归都可以获得其路径的一部分,那么就可以通过拼接的方式获取其路径。

6、采用递归方式,同时递归字典或列表:版本6(未完,待续。。。)

python获取字典末端value值的取值方式相关推荐

  1. Python+获取字典中某一个键的值

    class GetResponsePara(object):# 获取字典中的某一个键的值def dict_get(self, dic, locators, default=None):if not i ...

  2. python嵌套字典取值_python嵌套字典比较值与取值的实现示例

    python嵌套字典比较值与取值的实现示例 本文通过示例给大家介绍了python嵌套字典比较值,取值,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例代码 #取值import t ...

  3. python如何使用字典中的值并进行比较_python嵌套字典比较值与取值的实现示例

    前言 本文通过示例给大家介绍了python嵌套字典比较值,取值,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 示例代码 #取值import types allGuests = {' ...

  4. python权重是什么意思_在python带权重的列表中随机取值的方法

    1 random.choice python random模块的choice方法随机选择某个元素 foo = ['a', 'b', 'c', 'd', 'e'] from random import ...

  5. python循环展示大写字母_python调用大写函数python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...

  6. python中字典的循环遍历的两种方式

    开发中经常会用到对于字典.列表等数据的循环遍历,但是python中对于字典的遍历对于很多初学者来讲非常陌生,今天就来讲一下python中字典的循环遍历的两种方式. 注意: python2和python ...

  7. mysql1193 HY000_[MySQL参数取值] Status取值ERROR 1193 (HY000): Unknown system_MySQL

    bitsCN.com [MySQL参数取值] Status取值ERROR 1193 (HY000): Unknown system variable 'Innodb_buffer_pool_read_ ...

  8. Java基本数据类型默认值和取值范围详解

    Java基本数据类型有哪些?Java中的基本数据类型有,byte.short.int.long.float.double.char和.boolean这些,接下我们来了解一下它们的默认值和取值范围是怎样 ...

  9. [Python] 字典 get(key, default=None):获取字典中相应键的对应值

    转自:Python 字典(Dictionary) get()方法 功能: get() 函数和setdefault()函数返回指定键的值,如果值不在字典中返回默认值. 语法: dict.get(key, ...

  10. python获取字典键值集合_Python集合字典

    Python集合&字典 @ 字典 字典的几种定义方式 第一种 字典{key1 : value1, key2 : value2, ......} dict1 = {'one': 1, 'two' ...

最新文章

  1. 大学计算机专业和物理专业哪个难,大学里最难毕业的3大专业,尤其是最后一个...
  2. scala入门之识别函数式风格
  3. CSP认证201312-3最大的矩形[C++题解]:枚举
  4. 游戏行业案例 | 99.7% 的充值玩家比例提升,从何而来?
  5. nuxt.js 引入第三方插件报window is not defined
  6. 小K的农场(差分约束)
  7. Latex中将多个eps图片合并成一幅eps的代码和方法
  8. java 随机生成中文姓名 工具类
  9. 万字干货!《增长黑客》背后的逻辑
  10. 二叉树节点x所在的层数
  11. 暗影精灵2pro装Linux系统,暗影精灵2不支持linux双系统吗?
  12. Less -- 初见less(Less介绍 初次使用less 使用考拉编译less 盒子居中)
  13. win7计算机高级设置在哪,windows7投屏设置在哪里
  14. 教你几种方法最大限度减轻酒精对你身体的伤害
  15. 【论文阅读】深度学习去雾1——论文精选
  16. Intel系列CPU架构的发展史
  17. python开发工具排行榜_编程语言交互排行榜_人工智能的Python第一名
  18. ibm服务器装虚拟机,IBM-POWER8服务器虚拟化与系统安装使用手册.doc
  19. 程序人生 Hello’s P2P
  20. [Swift]国际化

热门文章

  1. uchome迁移问题
  2. 实验室服务器系统崩溃,选课系统崩溃解救报告
  3. iOS动画之大雪纷飞
  4. linux的dlan脚本,Linux DLNA
  5. 氟虫腈-13C2,15N2同位素内标的基质效应
  6. 鲲志说:向我跌宕起伏,喜忧参半的2022致敬!
  7. Qt利用avilib实现录屏功能_利用CE修改LOL实现各种功能(无限视距、锁定视距、攻击距离、炮塔范围、人物大小等)...
  8. AI上推荐 之 FiBiNET模型(特征重要性选择与双线性特征交叉)
  9. masm 16位汇编语法
  10. 序列化和反序列化 加上json数据流转换