欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python filter可变过滤条件过滤json列表

程序员文章站 2024-01-06 08:05:10
...

场景是这样的,假设有一个json用来表示一个学生的信息:

{
	"name" : "name",
	"age" : "age",
	"clazz" : "class",
	"school" : "school",
}

某次查询返回来的是一个josn列表 [{},{},{}…],而我需要对这些列表做一些过滤的操作。
类似找出所有 name=‘小明’ 的 json, 或者过找出所有 age=19 并且 class=三年级 的学生。

直接使用if枚举状态太多,有 n 个属性就要写 2 n 2^n 2n 个条件。所以想有没有更简单的写法。
一种想法是,写一个 filter_by 函数,默认全为None,此时不做任何过滤,仅有那些被赋值的参数才会作为过滤条件。
比如要找THU毕业的所有学生:

def filter_by(stu_info, clazz=None, name=None, age=None, school=None):
    params = locals()
    params.pop('stu_info')
    for key in params:
        if params[key] is None:
            continue
        if stu_info.get(key) != params[key]:
            return False
    return True

if __name__ == "__main__":
    json_list = [
        {
            "clazz": "三年级",
            "name": "小明",
            "age": 13,
            "school": "THU"
        },
        {
            "clazz": "五年级",
            "name": "小明",
            "age": 21,
            "school": "THU"
        },
        {
            "clazz": "七年级",
            "name": "小红",
            "age": 12,
            "school": "PKU"
        },
    ]
    filtered_list = list(filter(lambda x: filter_by(x, school="THU"), json_list))
    print(filtered_list)

结果:

[{'clazz': '三年级', 'name': '小明', 'age': 13, 'school': 'THU'}, 
 {'clazz': '五年级', 'name': '小明', 'age': 21, 'school': 'THU'}]

如果 json 属性非常多,那么可以使用参数列表来处理,修改 filter_by 函数:

def filter_by(stu_info, **kwargs):
    params = kwargs
    for key in params:
        if stu_info.get(key) != params[key]:
            return False
    return True

同样的使用方式:

  filtered_list = list(filter(lambda x: filter_by(x, school="THU"), json_list))
   print(filtered_list)

结果相同。

相比之下第二种方式更为灵活一些,但是需要对应对 json 结构比较了解,不然可能会写出实际不存在的一些参数。
第一种方式需要明确写出有那些参数,但是好处是如果传入不存在的参数解释器会有提醒。

上一篇:

下一篇: