在Python的实际开发中,嵌套字典是非常常见的数据结构,比如存储多层级的配置信息、接口返回的复杂数据等。很多时候我们需要先过滤掉嵌套字典中不符合条件的项,再对剩余项的键序进行重新排序,让数据结构更符合后续处理的要求。
基础场景:单层字典的过滤与键序重排
我们先从最简单的单层字典场景入手,假设我们有一个存储学生成绩的字典,需要过滤掉分数低于60分的项,再按照分数从高到低对键序进行排序。
实现这个需求可以分两步,第一步先过滤不符合条件的项,第二步对过滤后的字典按指定规则排序并生成新字典。下面是具体的代码示例:
# 原始学生成绩字典
score_dict = {
"张三": 85,
"李四": 52,
"王五": 90,
"赵六": 45,
"孙七": 78
}
# 过滤条件:分数大于等于60
def filter_condition(item):
return item[1] >= 60
# 第一步:过滤不符合条件的项
filtered_items = list(filter(filter_condition, score_dict.items()))
# 第二步:按分数从高到低排序,再重排键序
sorted_items = sorted(filtered_items, key=lambda x: x[1], reverse=True)
# 生成新的有序字典
new_score_dict = {}
for name, score in sorted_items:
new_score_dict[name] = score
print(new_score_dict)
运行上述代码后,输出的新字典会只包含分数大于等于60的学生,且键序按照分数从高到低排列,结果为{'王五': 90, '张三': 85, '孙七': 78}。
进阶场景:多层嵌套字典的处理
实际场景中更多遇到的是多层嵌套字典,比如下面的字典结构,存储了不同班级的学生信息,我们需要过滤掉每个班级中年龄小于18岁的学生,再按照年龄从小到大重排每个班级内的键序。
# 原始嵌套字典,外层键是班级,内层是学生的姓名和年龄
class_dict = {
"一班": {
"张三": 17,
"李四": 19,
"王五": 18
},
"二班": {
"赵六": 16,
"孙七": 20,
"周八": 18
}
}
# 过滤条件:年龄大于等于18
def age_filter(student_info):
return student_info[1] >= 18
# 处理嵌套字典的函数
def process_nested_dict(nested_dict, filter_func, sort_key, reverse=False):
result = {}
for class_name, students in nested_dict.items():
# 过滤当前班级不符合条件的学生
filtered_students = list(filter(filter_func, students.items()))
# 按指定规则排序
sorted_students = sorted(filtered_students, key=sort_key, reverse=reverse)
# 重排键序生成新的班级字典
new_class_dict = {}
for name, age in sorted_students:
new_class_dict[name] = age
result[class_name] = new_class_dict
return result
# 调用函数处理,按年龄从小到大排序
processed_dict = process_nested_dict(
class_dict,
age_filter,
lambda x: x[1],
reverse=False
)
print(processed_dict)
运行上述代码后,输出的结果中每个班级都过滤掉了年龄小于18岁的学生,且班级内的键序按照年龄从小到大排列,结果如下:
{
'一班': {'王五': 18, '李四': 19},
'二班': {'周八': 18, '孙七': 20}
}
通用处理方案:支持任意嵌套层级的递归实现
如果嵌套字典的层级不固定,比如有的内层还是字典,有的内层是列表,我们需要用递归的方式处理。下面的方案可以处理任意层级的嵌套字典,只要遇到字典类型就执行过滤和键序重排操作。
# 通用递归处理函数
def recursive_process_dict(data, filter_func, sort_key, reverse=False):
# 如果当前数据是字典,进行处理
if isinstance(data, dict):
# 过滤不符合条件的项,这里假设过滤条件针对字典的值,可根据实际需求调整
filtered_items = list(filter(filter_func, data.items()))
# 排序
sorted_items = sorted(filtered_items, key=sort_key, reverse=reverse)
# 生成新的有序字典,递归处理值
new_dict = {}
for k, v in sorted_items:
new_dict[k] = recursive_process_dict(v, filter_func, sort_key, reverse)
return new_dict
# 如果不是字典,直接返回原数据
else:
return data
# 测试任意嵌套层级的字典
test_dict = {
"部门A": {
"小组1": {
"员工1": 25,
"员工2": 17,
"员工3": 30
},
"小组2": {
"员工4": 16,
"员工5": 22
}
},
"部门B": {
"小组3": {
"员工6": 19,
"员工7": 15
}
}
}
# 过滤条件:值大于等于18
def value_filter(item):
return item[1] >= 18
# 按值从小到大排序
result = recursive_process_dict(
test_dict,
value_filter,
lambda x: x[1],
reverse=False
)
print(result)
上述递归方案可以适配不同层级的嵌套字典,只要遇到字典类型就会执行过滤和排序操作,最终输出的结果中所有不符合条件的项都会被删除,且键序按照指定规则重排。
注意事项
- Python 3.7及以上版本的字典是有序的,重排键序后生成的新字典会保持排序后的顺序,如果是更低版本可以使用
collections.OrderedDict来保持顺序。 - 过滤条件需要根据实际的数据结构调整,比如如果字典的值是复杂对象,过滤条件需要对应修改判断逻辑。
- 递归处理时要注意避免循环引用的问题,如果嵌套字典存在循环引用,需要额外增加判断逻辑防止无限递归。