You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效遍历Python嵌套字典?求优化多循环判断的方案

优化嵌套字典中特定字段的查找逻辑

首先提个小细节:你给出的初始代码里有个笔误——v1应该是v,不然会报未定义的错误哦。接下来咱们聊聊怎么优化这段逻辑,减少嵌套循环和判断,同时让代码更易读、更灵活。

你的需求回顾

我有一个嵌套结构的Python字典,除了values键外,还可能存在values1、values2等同类型的键。需要查找其中的random1和random2字段:若存在,则检查其下是否存在val字段。

字典示例:

d = {"values": [ { "name": "A1234", "description": "A1234-Description ", "random1": { "abcd": { "val": 1 } }, "random2": { "abcd": { "val": -1 } } }, { "name": "A4567", "description": "A4567-Description ", "random1": { "abcd": { "val": 1 } }, "random2": { "abcd": { "val": -1 } } }, { "name": "B1234", "description": "B1234-Description ", } ]}

初始代码(修正笔误后):

for i in d["values"]:
    for k, v in i.items():
        if k in ("random1", "random2") and "abcd" in v:
            if len(v["abcd"]) != 0:
                if "val" in v["abcd"]:
                    print("Found")
                else:
                    print("Not found")
            else:
                print("empty")

优化方案

1. 用字典get()干掉多层嵌套if

字典的get()方法是处理嵌套结构的神器——它允许你安全地获取深层键,不存在时返回默认值(比如空字典{}),这样可以把多层if判断合并成更简洁的逻辑:

# 定义要检查的目标字段
target_keys = ("random1", "random2")

# 先遍历所有类似values的键(values、values1、values2...)
for list_key in [k for k in d if k.startswith("values")]:
    # 遍历每个列表里的条目
    for item in d[list_key]:
        # 逐个检查目标字段
        for key in target_keys:
            # 逐层获取,不存在就返回空字典
            abcd_dict = item.get(key, {}).get("abcd")
            if not abcd_dict:
                print(f"{key} -> abcd 为空或不存在")
            elif "val" in abcd_dict:
                print(f"{key} -> 找到val: {abcd_dict['val']}")
            else:
                print(f"{key} -> abcd中没有val字段")

这种写法把原来的3层if压缩成了1层,逻辑更清晰,还避免了键不存在时的KeyError。

2. 用生成器表达式快速筛选结果

如果你不需要打印每一步,而是要收集所有符合条件的val信息,可以用生成器表达式(或者列表推导式)来简化循环,效率也更高:

from collections.abc import Iterable

target_keys = ("random1", "random2")

# 生成器:收集所有存在val的条目信息
valid_entries = (
    (list_key, item["name"], key, abcd["val"])
    # 遍历所有values开头的键
    for list_key in d if list_key.startswith("values")
    # 遍历每个列表的条目
    for item in d[list_key]
    # 遍历目标字段
    for key in target_keys
    # 用海象运算符赋值并判断:abcd存在且非空,同时包含val
    if (abcd := item.get(key, {}).get("abcd")) and isinstance(abcd, dict) and "val" in abcd
)

# 遍历结果
for entry in valid_entries:
    print(f"列表: {entry[0]}, 条目名称: {entry[1]}, 字段: {entry[2]}, val值: {entry[3]}")

这里用到了Python 3.8+的海象运算符:=,可以在条件判断里同时赋值,减少额外的变量声明。生成器是惰性求值的,不会一次性把所有结果加载到内存里,适合处理大字典。

3. 借助collections.ChainMap合并多列表遍历

如果你的字典里有多个values类列表(比如values、values1),想把它们合并成一个逻辑上的可迭代对象,不用创建新列表,可以用collections.ChainMap:

from collections import ChainMap

target_keys = ("random1", "random2")

# 把所有values开头的列表合并成一个ChainMap(不会复制数据,节省内存)
all_items = ChainMap(*[d[k] for k in d if k.startswith("values")])

for item in all_items:
    for key in target_keys:
        abcd_dict = item.get(key, {}).get("abcd")
        if not abcd_dict:
            print(f"{key} -> abcd 为空或不存在")
        elif "val" in abcd_dict:
            print(f"{key} -> 找到val: {abcd_dict['val']}")
        else:
            print(f"{key} -> abcd中没有val字段")

ChainMap只是把多个列表“链接”在一起,不会生成新的列表,对内存友好,尤其是当你的列表很大的时候。

4. 封装通用工具函数复用逻辑

如果需要频繁检查嵌套字典的深层路径,可以写一个通用函数,以后直接调用就行:

def get_nested_value(data: dict, path: Iterable, default=None):
    """
    获取嵌套字典中指定路径的值,路径不存在则返回default
    :param data: 原始字典
    :param path: 键的路径,比如["random1", "abcd", "val"]
    :param default: 路径不存在时的返回值
    """
    current = data
    for key in path:
        current = current.get(key, default)
        if current is default:
            break
    return current

# 使用示例
target_keys = ("random1", "random2")
for list_key in [k for k in d if k.startswith("values")]:
    for item in d[list_key]:
        for key in target_keys:
            val = get_nested_value(item, [key, "abcd", "val"])
            if val is not None:
                print(f"{key} -> 找到val: {val}")
            else:
                # 可以进一步判断是哪一层出了问题
                abcd = get_nested_value(item, [key, "abcd"])
                if abcd is None:
                    print(f"{key} -> abcd 不存在")
                elif not abcd:
                    print(f"{key} -> abcd 为空")
                else:
                    print(f"{key} -> abcd中没有val字段")

这个函数可以复用在任何嵌套字典的路径查找场景,让代码更模块化。

总结

  • 优先用dict.get()处理嵌套结构,减少KeyError和多层if;
  • 海象运算符:=能在条件中赋值,简化代码;
  • collections.ChainMap适合合并多列表遍历,节省内存;
  • 封装通用函数可以提升代码的可维护性和复用性。

内容的提问来源于stack exchange,提问作者Fresher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 11:42:55