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

Python中如何通过动态多段键字符串过滤字典值?

问题

我想通过输入动态键字符串来过滤字典中的指定值,比如键字符串格式为filter_key = "fdd.hello1"或者filter_key = "fdd.hello1.k1.k2.k3"。目前的实现代码仅支持最多2个分隔点的键字符串,如何修改才能适配任意长度的动态键?

现有代码如下:

import operator as op

d1 = {'name': 'test1',
        'with_child': ['c1', 'c2'],
        'fdd': {'hello1': 123, 'hello2': 234},
        'date': '2023-3-10'}

filter_key = "fdd.hello1"

def filter_value(val, filter_key):
    dot_count = op.countOf(filter_key, ".")
    filter_value = ""

    try:
        if dot_count == 0:
            filter_value = d1[filter_key]
        if dot_count == 1:
            f1,c1 = filter_key.split(".")
            filter_value = d1[f1][c1]
        elif dot_count == 2:
            f1,c1,c2 = filter_key.split(".")
            filter_value = d1[f1][c1][c2]
    except KeyError as e:
        print("123213123213")
    return filter_value

解决方案

方法1:循环遍历键路径

把键字符串按.分割成键列表,从字典根节点开始逐层向下访问,直到获取最终值。这种方法逻辑直观,便于调试和扩展额外逻辑。

修改后的代码:

d1 = {'name': 'test1',
        'with_child': ['c1', 'c2'],
        'fdd': {'hello1': 123, 'hello2': {'k1': {'k2': {'k3': 456}}}},
        'date': '2023-3-10'}

def filter_value(data, filter_key):
    current = data
    try:
        keys = filter_key.split(".")
        for key in keys:
            # 兼容列表索引(比如"with_child.0"可以取到'c1')
            current = current[int(key)] if key.isdigit() else current[key]
        return current
    except (KeyError, TypeError, IndexError) as e:
        # 捕获键不存在、节点不可索引、列表越界等错误
        print(f"获取值失败:{str(e)}")
        return ""

# 测试示例
print(filter_value(d1, "fdd.hello1"))  # 输出123
print(filter_value(d1, "fdd.hello2.k1.k2.k3"))  # 输出456
print(filter_value(d1, "with_child.0"))  # 输出c1
print(filter_value(d1, "invalid.key"))  # 捕获错误并返回空字符串

方法2:用functools.reduce简化代码

利用reduce函数将逐层取值的逻辑压缩为一行代码,适合追求代码精简的场景,底层逻辑和循环法一致。

代码实现:

from functools import reduce
import operator

d1 = {'name': 'test1',
        'with_child': ['c1', 'c2'],
        'fdd': {'hello1': 123, 'hello2': {'k1': {'k2': {'k3': 456}}}},
        'date': '2023-3-10'}

def get_item(obj, key):
    # 兼容列表索引的自定义取值函数
    return obj[int(key)] if key.isdigit() else obj[key]

def filter_value(data, filter_key):
    try:
        keys = filter_key.split(".")
        return reduce(get_item, keys, data)
    except (KeyError, TypeError, IndexError) as e:
        print(f"获取值失败:{str(e)}")
        return ""

# 测试示例
print(filter_value(d1, "fdd.hello1"))  # 输出123
print(filter_value(d1, "fdd.hello2.k1.k2.k3"))  # 输出456

注意点

  • 两种方法都扩展了错误捕获范围,不仅处理KeyError,还覆盖了节点不可索引、列表越界等场景
  • 新增了列表索引兼容逻辑,支持类似"with_child.0"的路径格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:43:20