Python中如何实现按最小location分组的多条件列表排序
问题描述
我有一个结构如下的字典列表:
[{'location':1, 'mgr':'Joe', 'region':'Frank'}, {'location':2, 'mgr':'Sam', 'region':'Jess'}, {'location':3, 'mgr':'Joe', 'region':'Frank'}, {'location':4, 'mgr':'Sue', 'region':'Frank'}, {'location':5, 'mgr':'Susan', 'region':'Jess'}]
需要将其排序为:同一region和mgr的条目归为一组,组的排序依据是该组内最小的location值,组内按location升序排列。期望的排序结果为:
[{'location':1,'mgr':'Joe','region':'Frank'},{'location':3,'mgr':'Joe','region':'Frank'},{'location':4, 'mgr':'Sue', 'region':'Frank'},{'location':2,'mgr':'Sam','region':'Jess'},{'location':5, 'mgr':'Susan', 'region':'Jess'}]
最终只需保证location的顺序正确即可。
尝试过遍历元素移动到新列表,但条目顺序仍错误;也尝试多键排序,却出现按字母排序或仅按location排序的问题,现寻求简洁可行的实现方案。
附上尝试的代码:
correctlist = [] originallist = [{'location':1,'mgr':'Joe','region':'Frank'},{'location':2,'mgr':'Sam','region':'Jess'},{'location':3,'mgr':'Joe','region':'Frank'},{'location':4, 'mgr':'Sue', 'region':'Frank'},{'location':5, 'mgr':'Susan', 'region':'Jess'}] # 期望结果:[{location:1,mgr:'Joe',region:'Frank'},{location:3,mgr:'Joe',region:'Frank'},{location:4, mgr:'Sue', region:'Frank'},{location:2,mgr:'Sam',region:'Jess'},{location:5, mgr:'Susan', region:'Jess'}] sortedlist = sorted(originallist, key=lambda k: (k['location'])) while sortedlist: for location in sortedlist: currregion = location['region'] currmgr = location['mgr'] for locationin sortedlist: if location['region'] == currregion and location['mgr'] == currmgr: correctlist.append(number) sortedlist.remove(number) for location in sortedlist: if location['region'] == curregion: currmgr = location['mgr'] for locationin sortedlist: if location['mgr'] == currmgr and location['region'] == curregion: correctlist.append(location) sortedlist.remove(location)
简洁实现方案
可以分两步完成需求:
- 先统计每个
(region, mgr)组合对应的最小location值,作为组排序的依据 - 对原列表进行多键排序,优先级依次为:
region、组最小location、当前元素的location
具体代码如下:
originallist = [ {'location':1, 'mgr':'Joe', 'region':'Frank'}, {'location':2, 'mgr':'Sam', 'region':'Jess'}, {'location':3, 'mgr':'Joe', 'region':'Frank'}, {'location':4, 'mgr':'Sue', 'region':'Frank'}, {'location':5, 'mgr':'Susan', 'region':'Jess'} ] # 统计每个(region, mgr)组的最小location group_min_loc = {} for item in originallist: key = (item['region'], item['mgr']) if key not in group_min_loc or item['location'] < group_min_loc[key]: group_min_loc[key] = item['location'] # 执行排序 result = sorted( originallist, key=lambda x: (x['region'], group_min_loc[(x['region'], x['mgr'])], x['location']) ) print(result)
代码说明
- 第一步用字典
group_min_loc记录每个组的最小location,确保组的排序符合要求 - 排序时,先按
region聚合同区域条目,再按组的最小location确定组的先后顺序,最后按当前元素的location完成组内升序排列 - 代码时间复杂度为O(n log n),属于高效排序实现,运行结果完全匹配期望
内容的提问来源于stack exchange,提问作者PersistentDabbler
相关产品推荐
相关产品推荐

