Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
857 views
in Technique[技术] by (71.8m points)

sorting - How can I sort tuples by reverse, yet breaking ties non-reverse? (Python)

If I have a list of tuples:

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

How can I sort the list as you might see in a scoreboard - such that it will sort the score from biggest to smallest, but break ties alphabetically by name?

So after the sort, the list should look like:

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

At the moment all I can do is results.sort(reverse=True), but breaks ties reverse alphabetically too...

Any help would be much appreciated. Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...