11

如果我有一个元组列表:

results = [('10', 'Mary'), ('9', 'John'), ('10', 'George'), ('9', 'Frank'), ('9', 'Adam')]

我如何对列表进行排序,就像您在记分牌中看到的那样 - 这样它会将分数从大到小排序,但按名称的字母顺序打破平局?

因此,排序后,列表应如下所示:

results = [('10', 'George'), ('10', 'Mary'), ('9', 'Adam'), ('9', 'Frank'), ('9', 'John')]

目前我所能做的就是results.sort(reverse=True),但打破关系也按字母顺序反转......

任何帮助将非常感激。谢谢!

4

4 回答 4

24

The simplest way to achieve what you want is to use the fact that python sort is stable. This allows to first sort alphabetically and then by score:

In [11]: results = [(10, 'Mary'), (9, 'John'), (10, 'George'), (9, 'Frank'), (9, 'Adam')]

In [12]: results.sort(key=lambda x: x[1])

In [13]: results.sort(key=lambda x: x[0], reverse=True)

In [14]: results
Out[14]: [(10, 'George'), (10, 'Mary'), (9, 'Adam'), (9, 'Frank'), (9, 'John')]

The first sort sorts alphabetically, in ascending order. The second sort sorts by score, in descending order, maintaining the relative order of elements with equal score.

You can do this to do even more complex sorts. Just remember that you must first sort by the secondary key, and then by the first key. (If you have three keys, first sort by the third, then by the second, and lastly by the main key).

If you don't want to call sort twice you'll have to write a more complex key function. Something like:

In [50]: def key(elem):
    ...:     return elem[0], [-ord(c) for c in elem[1]]

In [51]: sorted(results, key=key, reverse=True)
Out[51]: [(10, 'George'), (10, 'Mary'), (9, 'Adam'), (9, 'Frank'), (9, 'John')]

In particular, every time you have something sorted in lexicographic order(such as strings, tuples, lists etc.), you can invert the order by changing the sign to all the elements.

于 2013-08-24T06:50:24.097 回答
7

sort方法接受可选key参数。

key 指定一个参数的函数,用于从每个列表元素中提取比较键

您需要将字符串转换为数字:

>>> results = [('10', 'Mary'), ('9', 'John'), ('10', 'George'), ('9', 'Frank'), ('9', 'Adam')]
>>> results.sort(key=lambda x: (int(x[0]), x[1]), reverse=True)
>>> results
[('10', 'Mary'), ('10', 'George'), ('9', 'John'), ('9', 'Frank'), ('9', 'Adam')]
于 2013-08-24T04:46:11.343 回答
1

You can have very granular control on how to sort each of the values in a tuple with sort method's key parameter. For example:

In [41]: results = [('10', 'Mary'), ('9', 'John'), ('10', 'George'), ('9', 'Frank'), ('9', 'Adam')]

In [42]: results.sort(key=lambda (score, name): (-int(score), name))

In [43]: results
Out[43]: 
[('10', 'George'),
 ('10', 'Mary'),
 ('9', 'Adam'),
 ('9', 'Frank'),
 ('9', 'John')]
于 2017-04-17T08:33:50.287 回答
-1

只需使用sorted就足够了

>>> sorted(results)
[('10', 'George'), ('10', 'Mary'), ('9', 'Adam'), ('9', 'Frank'), ('9', 'John')]

默认cmp函数通过按顺序比较元组的每个成员(从 0 到 n)来检查元组的优先级

于 2013-08-24T04:45:57.897 回答