Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sort dictionary by descending values and then by keys alphabetically

Tags:

python

sorting

I have the following dictionary:

fruits = {
    "apple": 5,
    "Apple": 5,
    "orange": 5,
    "strawberry": 3,
    "blueberry": 1
}

I need to print out a list of the two keys with the highest values. Ties need to be broken alphabetically A-Z with capital letters taking precedence over lowercase ones. Running the following sorts by the counts, but doesn't break the ties:

popular_fruits = sorted(fruits, key=fruits.get, reverse=True)
print(popular_fruits[0:2])

How can I accomplish this?

like image 309
Matt Whitehead Avatar asked Jun 16 '18 06:06

Matt Whitehead


2 Answers

You can use something like this:

popular_fruits = sorted(fruits, key=lambda x: (-fruits[x], x))
print(popular_fruits[0:2])

EDIT:

A negation before fruits[x] is used to reverse the decreasing numeric ordering and in case of a tie the order is determined by the second argument of the tuple (alphabetically).

One cannot simply use sorted(fruits, key=lambda x: (fruits[x], x), reverse=True) because it will reverse ordering for both tuple elements, but we need to do it for the first element only.

like image 92
taras Avatar answered Oct 22 '22 03:10

taras


You can do secondary sorting by using a tuple. I used -1 * the value to reverse it. "Capitals first" is the default sorting order for Python.

This is wrong even though it got some upvotes:

popular_fruits = sorted(fruits, key = lambda x: (-1 * x[1], x[0]))

# ['Apple', 'apple']

It should be as taras posted:

popular_fruits = sorted(fruits, key = lambda x: (-fruits[x], x))

I was sorting by the first and second letter and happened to give the first two items in order correctly but is actually completely wrong. I'll keep this up if people think it is useful to see an error that you can make by confusing a dict for a list of lists/tuples.

like image 24
Zev Avatar answered Oct 22 '22 02:10

Zev