如何基于多键值对在字典列表中实现条件逻辑并标记Executor不匹配项
解决字典列表的分组条件标记问题
我来帮你搞定这个需求——核心就是先按指定字段分组,再对每组做条件校验,最后标记符合要求的元素。咱们一步步来:
思路拆解
- 分组聚合:把拥有相同
Component、Id、Name的字典归为一组,这是后续判断的基础。 - 多条件校验:对每个分组检查三个核心条件:
- 组内每个元素的
Abs Diff都大于0 - 组内所有
Difference的总和小于1 - 组内的
Executor没有重复(互不相同)
- 组内每个元素的
- 标记元素:如果分组满足所有条件,就给组内每个字典加上
"Result": "Mismatched Executor"。
完整代码实现
from itertools import groupby # 你的原始数据 d_dict = [ {'Abs Diff': 10,'Difference':10, 'Component': 'Local Market', 'Id':'123', 'Name': 'LAT', 'Executor':'AB'}, {'Abs Diff': 20,'Difference':20, 'Component': 'Local Market', 'Id':'123', 'Name': 'LAT', 'Executor':'B'}, {'Abs Diff': 30,'Difference':-30, 'Component': 'Local Market', 'Id':'123', 'Name': 'LAT', 'Executor':'BA'}, {'Abs Diff': 23,'Difference':23, 'Component': 'USD Market', 'Id':'456', 'Name': 'LAT', 'Executor':'CB'}, {'Abs Diff': 25,'Difference':25, 'Component': 'USD Market', 'Id':'456', 'Name': 'LAT', 'Executor':'C'}, {'Abs Diff': 48,'Difference':-48, 'Component': 'USD Market', 'Id':'456', 'Name': 'LAT', 'Executor':'CB'}, {'Abs Diff': 5,'Difference':5, 'Component': 'Price', 'Id':'123', 'Name': 'LAT', 'Executor':'AB'}, {'Abs Diff': 5,'Difference':5, 'Component': 'Price', 'Id':'123', 'Name': 'LAT', 'Executor':'B'}, {'Abs Diff': 10,'Difference':-10, 'Component': 'Price', 'Id':'123', 'Name': 'LAT', 'Executor':'BA'} ] # 第一步:先排序,确保groupby能正确分组(groupby只认连续的相同元素) sorted_data = sorted(d_dict, key=lambda x: (x['Component'], x['Id'], x['Name'])) result = [] # 第二步:按Component、Id、Name分组处理 for group_key, group_items in groupby(sorted_data, key=lambda x: (x['Component'], x['Id'], x['Name'])): items_list = list(group_items) # 检查条件1:所有元素的Abs Diff都大于0 all_abs_positive = all(item['Abs Diff'] > 0 for item in items_list) # 检查条件2:Difference总和小于1 total_diff = sum(item['Difference'] for item in items_list) diff_sum_ok = total_diff < 1 # 检查条件3:Executor互不重复(集合去重后长度和原列表一致) executors = [item['Executor'] for item in items_list] no_dup_executors = len(set(executors)) == len(executors) # 如果所有条件都满足,给组内元素添加标记 if all_abs_positive and diff_sum_ok and no_dup_executors: for item in items_list: item['Result'] = 'Mismatched Executor' # 把处理后的元素加入结果列表 result.extend(items_list) # 可以打印结果看看 for entry in result: print(entry)
关键细节说明
- 排序的必要性:
itertools.groupby不会自动把所有相同键的元素凑到一起,只会分组连续的相同元素,所以必须先按分组键排序,这是新手容易踩的坑。 - 条件校验的简洁写法:用
all()、sum()和集合的特性,能快速完成条件判断,比循环逐个检查更高效简洁。 - 关于你的示例注意点:你给出的期望结果里,
USD Market分组有两个Executor: CB,按规则里的“Executor互不相同”条件,这个分组其实不满足标记要求。如果你的实际需求是“组内存在至少两个不同的Executor”,只需要把no_dup_executors的判断改成len(set(executors)) > 1就行。
内容的提问来源于stack exchange,提问作者deepvalue
相关产品推荐
相关产品推荐

