全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

Python中深度嵌套字典与列表的数据提取与条件过滤指南

本教程旨在详细讲解如何在python中处理复杂的深度嵌套字典和列表数据结构。我们将通过一个实际案例,演示如何有效地遍历多层数据,提取特定字段(如`asset`、`free`、`locked`),并应用条件过滤(例如,排除`free`和`locked`字段均为'0'的条目),最终构建出符合需求的结果集。

在现代数据处理中,我们经常会遇到来自API响应、配置文件或日志等来源的复杂数据结构,它们通常以JSON格式呈现,并在Python中表现为嵌套的字典和列表。有效地从这些结构中提取所需信息并进行过滤,是数据处理的核心技能之一。

数据结构概览

假设我们有以下Python字典数据,其中包含多层嵌套的列表和字典:

repo = {
    'code': 200,
    'msg': '',
    'snapshotVos': [
        {
            'data': {
                'balances': [
                    {'asset': 'ADD', 'free': '10', 'locked': '0'},
                    {'asset': 'RDP', 'free': '0', 'locked': '0'},
                    {'asset': 'SHIB', 'free': '0', 'locked': '947415'}
                ],
                'totalAsset': '152'
            },
            'type': 'spot',
            'updateTime': 1703807999000
        }
    ]
}

这个repo字典的结构如下:

  • 顶层包含code、msg和snapshotVos。
  • snapshotVos是一个列表,其中包含一个或多个字典。
  • snapshotVos列表中的每个字典又包含data、type和updateTime。
  • data是一个字典,其中包含balances和totalAsset。
  • balances是一个列表,其中包含多个字典,每个字典代表一个资产的余额信息,包括asset、free和locked。

目标:提取与过滤

我们的目标是从上述repo字典中提取balances列表中的所有条目,但需要满足以下两个条件:

  1. 获取每个条目的asset、free和locked字段的值。
  2. 过滤掉那些free和locked字段值均为'0'的条目。

最终结果应是一个列表,其中包含符合条件的资产余额信息。

逐步解析与实现

为了实现上述目标,我们需要逐层深入数据结构,并应用适当的循环和条件判断。

1. 遍历 snapshotVos 列表

首先,我们需要访问repo字典中的snapshotVos键,它是一个列表。由于这个列表可能包含多个元素(尽管我们的示例中只有一个),我们需要一个循环来遍历它。

rows1 = [] # 用于存储最终结果的列表
for item in repo['snapshotVos']:
    # 在这里处理每个item
    pass

2. 访问 data 和 balances

在snapshotVos列表的每个item中,我们感兴趣的数据位于item['data']['balances']。balances本身又是一个列表,其中包含多个资产字典。

rows1 = []
for item in repo['snapshotVos']:
    data_content = item['data']
    balances_list = data_content['balances']
    # 现在,balances_list 是一个包含资产字典的列表
    pass

3. 遍历 balances 列表并应用过滤条件

现在我们有了balances_list,我们需要再次使用循环来遍历其中的每一个资产字典(我们称之为balance)。在每次迭代中,我们将应用过滤条件。

rows1 = []
for item in repo['snapshotVos']:
    for balance in item['data']['balances']:
        # 检查过滤条件:如果 'free' 和 'locked' 字段不都为 '0'
        if not (balance['free'] == '0' and balance['locked'] == '0'):
            # 提取所需的值
            # 原始问题要求“获取键从 'asset', 'free', 'locked'”,
            # 答案提供的是这些键的值列表。
            # 如果需要的是值列表:
            val = [balance['asset'], balance['free'], balance['locked']]

            # 如果需要的是一个包含这些键值对的字典:
            # val = {'asset': balance['asset'], 'free': balance['free'], 'locked': balance['locked']}

            # 确保不添加重复的条目 (如果需要去重)
            if val not in rows1:
                rows1.append(val)

关于去重说明: 原始答案中的if val not in rows1: 是为了确保最终结果列表中不包含重复的条目。如果数据源本身保证不重复,或者允许重复,则可以省略此检查以提高效率。

完整代码示例

将上述步骤整合,得到完整的解决方案代码:

repo = {
    'code': 200,
    'msg': '',
    'snapshotVos': [
        {
            'data': {
                'balances': [
                    {'asset': 'ADD', 'free': '10', 'locked': '0'},
                    {'asset': 'RDP', 'free': '0', 'locked': '0'},
                    {'asset': 'SHIB', 'free': '0', 'locked': '947415'}
                ],
                'totalAsset': '152'
            },
            'type': 'spot',
            'updateTime': 1703807999000
        },
        # 假设 snapshotVos 中可能有更多元素,或者 balances 中有重复项
        {
            'data': {
                'balances': [
                    {'asset': 'ADD', 'free': '10', 'locked': '0'}, # 这是一个重复项
                    {'asset': 'BTC', 'free': '0.5', 'locked': '0.1'}
                ],
                'totalAsset': '200'
            },
            'type': 'margin',
            'updateTime': 1703808000000
        }
    ]
}

rows1 = [] # 用于存储最终结果的列表

for item in repo['snapshotVos']:
    for balance in item['data']['balances']:
        # 检查过滤条件:如果 'free' 和 'locked' 字段不都为 '0'
        if not (balance['free'] == '0' and balance['locked'] == '0'):
            # 提取 'asset', 'free', 'locked' 的值作为一个列表
            # 如果你希望得到一个字典,可以改为:
            # val = {'asset': balance['asset'], 'free': balance['free'], 'locked': balance['locked']}
            val = [balance['asset'], balance['free'], balance['locked']]

            # 检查是否已存在,避免重复添加
            if val not in rows1:
                rows1.append(val)

print(rows1)

结果分析

运行上述代码,将得到如下输出:

[['ADD', '10', '0'], ['SHIB', '0', '947415'], ['BTC', '0.5', '0.1']]

从输出中可以看到:

  • ['ADD', '10', '0'] 被包含,因为它虽然locked为'0',但free不为'0'。
  • ['RDP', '0', '0'] 被排除,因为其free和locked均为'0'。
  • ['SHIB', '0', '947415'] 被包含。
  • ['BTC', '0.5', '0.1'] 被包含。
  • 重复的['ADD', '10', '0']只出现了一次,这得益于if val not in rows1:的去重逻辑。

注意事项与进阶技巧

1. 处理缺失键

在实际数据中,字典的键可能不是每次都存在。为了避免KeyError,可以使用字典的get()方法提供默认值,或者使用try-except块。

# 使用 .get() 方法
asset = balance.get('asset', 'N/A')
free = balance.get('free', '0') # 如果键不存在,默认为 '0'
locked = balance.get('locked', '0')

2. 返回字典而非值列表

如果希望结果列表中的每个元素是一个字典,而不是值的列表,可以修改val的构建方式:

# ... (循环部分相同)
if not (balance.get('free', '0') == '0' and balance.get('locked', '0') == '0'):
    val = {
        'asset': balance.get('asset'),
        'free': balance.get('free'),
        'locked': balance.get('locked')
    }
    if val not in rows1: # 注意:字典的去重比较复杂,可能需要自定义逻辑
        rows1.append(val)

如果返回字典,if val not in rows1: 的去重逻辑可能需要更精细的实现,因为字典的相等性比较是基于键值对的。

3. 使用列表推导式简化代码

对于这种提取和过滤操作,Python的列表推导式(List Comprehension)可以使代码更简洁、更具可读性:

rows1_comprehension = [
    [balance['asset'], balance['free'], balance['locked']]
    for item in repo['snapshotVos']
    for balance in item['data']['balances']
    if not (balance['free'] == '0' and balance['locked'] == '0')
]
# 注意:列表推导式默认不会去重。如果需要去重,可以转换为set再转回list,
# 或者使用更复杂的推导式结合set。
# 例如,如果需要去重并保持顺序,可以这样做:
seen = set()
unique_rows1 = []
for row in rows1_comprehension:
    if tuple(row) not in seen: # 列表不能直接放入set,需要转换为不可变的tuple
        seen.add(tuple(row))
        unique_rows1.append(row)

print(unique_rows1)

4. 类型转换

请注意,示例数据中的free和locked值是字符串(例如'10'、'0')。如果需要进行数值比较或计算,务必将其转换为整数或浮点数。

# 过滤条件可以改为数值比较
# if not (int(balance.get('free', '0')) == 0 and int(balance.get('locked', '0')) == 0):

在进行类型转换前,务必确保字符串可以安全地转换为数字,否则可能引发ValueError。

总结

从嵌套的Python字典和列表中提取和过滤数据是日常编程中的常见任务。通过理解数据结构、运用嵌套循环和条件判断,我们可以精确地定位并处理所需的数据。列表推导式提供了一种更Pythonic、更简洁的解决方案。在实际应用中,还需考虑键的缺失、数据类型转换以及去重等问题,以确保代码的健壮性和准确性。


# python  # js  # json  # app  # 配置文件  # 键值对  # btc 


相关文章: 专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?  建站之星2.7模板:企业网站建设与h5定制设计专题  建站之星代理平台如何选择最佳方案?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  如何在Golang中使用replace替换模块_指定本地或远程路径  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  如何在景安云服务器上绑定域名并配置虚拟主机?  详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)  制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  javascript中对象的定义、使用以及对象和原型链操作小结  mc皮肤壁纸制作器,苹果平板怎么设置自己想要的壁纸我的世界?  建站之星安装提示数据库无法连接如何解决?  招商网站制作流程,网站招商广告语?  c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】  如何有效防御Web建站篡改攻击?  如何用5美元大硬盘VPS安全高效搭建个人网站?  如何通过FTP服务器快速搭建网站?  合肥做个网站多少钱,合肥本地有没有比较靠谱的交友平台?  如何在万网主机上快速搭建网站?  C#如何使用XPathNavigator高效查询XML  如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?  如何用PHP快速搭建高效网站?分步指南  代刷网站制作软件,别人代刷火车票靠谱吗?  ,石家庄四十八中学官网?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  平台云上自主建站:模板化设计与智能工具打造高效网站  佛山企业网站制作公司有哪些,沟通100网上服务官网?  建站主机选购指南:核心配置与性价比推荐解析  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  宝塔建站教程:一键部署配置流程与SEO优化实战指南  哈尔滨网站建设策划,哈尔滨电工证查询网站?  网站制作外包价格怎么算,招聘网站上写的“外包”是什么意思?  Java解压缩zip - 解压缩多个文件或文件夹实例  b2c电商网站制作流程,b2c水平综合的电商平台?  宝塔建站助手安装配置与建站模板使用全流程解析  建站主机功能解析:服务器选择与快速搭建指南  建站之星如何实现PC+手机+微信网站五合一建站?  如何确保西部建站助手FTP传输的安全性?  专业网站建设制作报价,网页设计制作要考什么证?  长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?  外贸公司网站制作哪家好,maersk船公司官网?  新网站制作渠道有哪些,跪求一个无线渠道比较强的小说网站,我要发表小说?  广州商城建站系统开发成本与周期如何控制?  开封网站制作公司,网络用语开封是什么意思?  如何在Tomcat中配置并部署网站项目?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  如何选择高性价比服务器搭建个人网站?  建站主机系统SEO优化与智能配置核心关键词操作指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。