Python排序问题

3 投票
5 回答
585 浏览
提问于 2025-04-16 01:46

我需要在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定义函数同样有效,而且可读性更好。

撰写回答