У меня есть список объектов. Каждый объект имеет два атрибута: DispName
и MachID
. DispName
может начинаться с theoretical
или быть чем-то другим.Сортировка сгруппированных объектов
мне нужно отсортировать этот список следующим образом:
- первым по алфавиту в
MachID
.- внутри каждой подгруппы
MachID
первый объект, где имя начинается сtheoretical
- затем другие объекты, отсортированные в алфавитном порядке.
- внутри каждой подгруппы
Это код, который я есть сейчас, который работает и производит необходимый выход, но мне было интересно, если я мог бы написать это более вещий, возможно, делает использование groupby
? (Мое оправдание для camelCasing).
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)