我有一个对象列表。每个对象都有两个属性:DispName 和MachID。 DispName 可以以 theoretical 开头,也可以是其他内容。
我需要按以下方式对这个列表进行排序:
- 首先按照
MachID的字母顺序排列。- 在每个
MachID子组中,首先是名称以theoretical开头的对象 - 然后其他对象按字母顺序排序。
- 在每个
这是我现在的代码,它可以工作并产生所需的输出,但我想知道我是否可以编写更 pythonic 的代码,也许可以使用 groupby? (我对驼峰式的借口)。
from collections import defaultdict, namedtuple
from operator import attrgetter
Mapping = namedtuple('Mapping', ['DispName', 'MachID'])
objectList = [Mapping('map 2 (MT1)', 'MT1'),
Mapping('theoretical (MT1)', 'MT1'),
Mapping('map 3 (MT2)', 'MT2'),
Mapping('theoretical (MT2)', 'MT2'),
Mapping('map 1 (MT1)', 'MT1'),
Mapping('map 2 (MT2)', 'MT2')]
def complexSort(objectList):
objectDict = defaultdict(list)
sortedMappingList = []
# group by machine ID
for obj in objectList:
objectDict[obj.MachID].append(obj)
# loop over the mappings sorted alphabetically by machine ID
for machID in sorted(objectDict.keys()):
mappings = objectDict[machID]
nonTheoreticalMappings = []
for mapping in mappings:
if mapping.DispName.startswith('theoretical'):
# if we encounter the theoretical mapping, add it first
sortedMappingList.append(mapping)
else:
# gather the other mappings in a sublist
nonTheoreticalMappings.append(mapping)
# and add that sublist sorted alphabetically
sortedMappingList.extend(sorted(nonTheoreticalMappings,
key=attrgetter('DispName')))
return sortedMappingList
for mapping in complexSort(objectList):
print mapping.DispName
产生:
theoretical (MT1)
map 1 (MT1)
map 2 (MT1)
theoretical (MT2)
map 2 (MT2)
map 3 (MT2)
请您参考如下方法:
只需将 sorted 与 key 一起使用即可生成您想要的顺序。由于元组是按字典顺序排列的,因此生成元组的 key 应该可以很好地工作。
def sort_key(thing):
return (thing.MachID, not thing.DispName.startswith('theoretical'))
sorted(objectList, key=sort_key) # returns a list sorted the way you want
