Luke21
Luke21

Reputation: 51

Sort dictionary by value, then by key

Hey I am trying to sort a dictionary by value from highest to lowest value. Howevet I want the items with same values to be sorted by key.

The following code does not work

dictionary = {"Sophie": 23, "Alfred": 23, "Zelda":22, "Betty":23}
sorted(dictionary.items(), key=lambda t: t[::-1])

Output:

[('Zelda', 22), ('Alfred', 23), ('Betty', 23), ('Sophie', 23)]

Expected output:

[('Alfred', 23), ('Betty', 23), ('Sophie', 23), ('Zelda', 22)]

ordered by decreasing value, then by key (alphabetical)

Upvotes: 5

Views: 1377

Answers (2)

TERMINATOR
TERMINATOR

Reputation: 1258

Option1

This is he more modern solution that will only work in python3.x, this is the same aproach the question took.Instead of t[::-1] being the index you need to use t: (-t[1], t[0]) .-t[1] sorts the names in ascending order because it has been negted. t[0]sorts keys in descending order. Here is the code:

dictionary = {"Sophie": 23, "Alfred": 23, "Zelda":22, "Betty":23}
reversed_dict= dict(sorted(dictionary.items(), key=lambda t: (-t[1], t[0])))
print(reversed_dict)

Output:

{'Alfred': 23, 'Betty': 23, 'Sophie': 23, 'Zelda': 22}

Option2

This is the more portable solution and works in all versions of python.This aproach requires you to import the operator library bfore you can begin. sorted(dictionary.items(), key=operator.itemgetter(0)) sorts the names in ascending order then sorted(reversed_dict, key=operator.itemgetter(1), reverse=True)) orders the keys in descending order.

Here is the code:

import operator

dictionary = {"Sophie": 23, "Alfred": 23, "Zelda":22, "Betty":23}
reversed_dict = sorted(dictionary.items(), key=operator.itemgetter(0))
reversed_dict = dict(sorted(reversed_dict, key=operator.itemgetter(1), reverse=True))
print(reversed_dict)

Output:

{'Alfred': 23, 'Betty': 23, 'Sophie': 23, 'Zelda': 22}

Upvotes: 2

blhsing
blhsing

Reputation: 107124

Since you want to sort with one key (the value) in descending order and a secondary key (the name) in ascending order, simply reversing the sorting order would not work. Instead, you should construct a tuple of the value and the name, with the value negated to sort it in descending order:

sorted(dictionary.items(), key=lambda t: (-t[1], t[0]))

Upvotes: 4

Related Questions