Python排序问题
我需要在Python中对以下的元组列表进行排序:
ListOfTuples = [('10', '2010 Jan 1;', 'Rapoport AM', 'Role of antiepileptic drugs as preventive agents for migraine', '20030417'), ('21', '2009 Nov;', 'Johannessen SI', 'Antiepilepticdrugs in epilepsy and other disorders--a population-based study of prescriptions', '19679449'),...]
我的目的是先按降序排列年份(listOfTuples[2]),然后再按升序排列作者(listOfTuples[1]):
sorted(result, key = lambda item: (item[1], item[2]))
但是这样做不行。我该如何保持排序的稳定性呢?
5 个回答
0
这里有一个适用于所有情况的习语,甚至是那些你不能否定的东西,比如字符串:
data = [ ('a', 'a'), ('a', 'b'), ('b','a') ]
def sort_func( a, b ):
# compare tuples with the 2nd entry switched
# this inverts the sorting on the 2nd entry
return cmp( (a[0], b[1]), (b[0], a[1]) )
print sorted( data ) # [('a', 'a'), ('a', 'b'), ('b', 'a')]
print sorted( data, cmp=sort_func ) # [('a', 'b'), ('a', 'a'), ('b', 'a')]
2
最简单的方法是分别对每个关键值进行排序。你可以从最不重要的关键开始,逐步向最重要的关键排序。
在这个例子中:
import operator
ListOfTuples.sort(key=operator.itemgetter(2))
ListOfTuples.sort(key=lambda x: x[1][:4], reverse=True)
之所以这样做是因为Python的排序总是保持稳定,即使你使用了反向排序的选项:也就是说,反向排序并不是先排序再反转(这样会失去稳定性),而是在反转后仍然保持稳定。
当然,如果你有很多关键列,这样做可能会效率不高,因为它会多次进行完整的排序。
你不需要把年份转换成数字,因为这是一个真正的反向排序,当然如果你想的话也可以这样做。
4
def descyear_ascauth(atup):
datestr = atup[1]
authstr = atup[2]
year = int(datestr.split(None, 1)[0])
return -year, authstr
... sorted(result, key=descyear_ascauth) ...
注意:你需要把年份提取出来,并且要以整数的形式(而不是字符串),这样你才能改变它的符号——这一步是满足“降序”要求的关键技巧。虽然可以把所有内容压缩到一个lambda
表达式里,但这样做没有必要,因为使用def
定义函数同样有效,而且可读性更好。