Skip to main content
 首页 » 编程设计

python之对分组对象进行排序

2025年05月04日17qlqwjy

我有一个对象列表。每个对象都有两个属性: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