使用装饰-排序-去装饰的旧方法¶
这个三个步骤被称为 Decorate-Sort-Undecorate :
首先,初始列表使用控制排序顺序的新值进行修饰。
然后,装饰列表已排序。
最后,删除装饰,创建一个仅包含新排序中初始值的列表。
例如,要使用DSU方法按 grade 对学生数据进行排序:
>>>decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
>>>decorated.sort()
>>>[student for grade, i, student in decorated] # undecorate
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
这方法语有效是因为元组按字典顺序进行比较,先比较第一项;如果它们相同则比较第二个项目,依此类推。
不一定在所有情况下都要在装饰列表中包含索引 i ,但包含它有两个好处:
排序是稳定的——如果两个项具有相同的键,它们的顺序将保留在排序列表中。
原始项目不必具有可比性,因为装饰元组的排序最多由前两项决定。 因此,例如原始列表可能包含无法直接排序的复数。
这个方法的另一个名字是 Randal L. Schwartz 在 Perl 程序员中推广的 Schwartzian transform。
既然 Python 排序提供了键函数,那么通常不需要这种技术。