Reputation: 5
I recently started learning Python, so I started learning the basics first. Once I got to dictionaries, I came up with a pretty "neat" challenge that I have tried wrapping my head around for quite a while but wasn't able to. I wanted to sort a dictionary based on its values in ascending order, while also taking into consideration the first keys that appear in the original, untouched dictionary.
To be more clear, let's say if we were given the following dictionary:
dictionary = {"A": 5, "B": 5, "C": 11, "D": 10, "E": 5, "F": 5, "G": 5}
I wanted to sort in such a way so we'd get:
{"C": 11, "D": 10, "G": 5, "F": 5, "E": 5, "B": 5, "A": 5} # Ascending order, with the keys in the
# beginning of the original dictionary being at the end here
I attempted coming up with some creative ways of solving it, but nothing really worked. One of the things I tried was first sorting the list by its values in ascending order and then take the values from the original dictionary and comparing it against the ones the sorted version of that dictionary, and then make some adjustments, but that seems a little too complicated, and I just wanted to know if there's perhaps a more elegant way of solving this problem without using any external libraries, but just using built-in dictionary provided functionality.
Upvotes: 0
Views: 58
Reputation: 1430
dictionary = {"A": 5, "B": 5, "C": 11, "D": 10, "E": 5, "F": 5, "G": 5}
keys = list(dictionary)
result = {k: v for k, v in sorted(dictionary.items(),
key=lambda item: (item[1], keys.index(item[0])),
reverse=True)}
print(result)
>>>> {'C': 11, 'D': 10, 'G': 5, 'F': 5, 'E': 5, 'B': 5, 'A': 5}
Upvotes: 0
Reputation: 1906
It's not advisable to assume that dictionaries in python can maintain order. In computer science, dictionaries (and sets) are usually considered as non ordered. Conceptually it is better to represent order with a list.
I also wouldnt assume that because I'm using python 3.6 then the plain dictionary will maintain order. You never know when your code could be used in another version of python. However there exists the possibility of using an OrderedDict
https://docs.python.org/2/library/collections.html#collections.OrderedDict
Once you determine the best way to keep that order, you can use the accepted answer to sort your entries.
Upvotes: 1
Reputation: 133544
Supported in Py 3.7+
First sort dict.items()
by descending value, and then index of each key, value pair
>>> d = {"A": 5, "B": 5, "C": 11, "D": 10, "E": 5, "F": 5, "G": 5}
>>> d_items_sorted = sorted(enumerate(d.items()),
key=lambda x: (x[1][1], x[0]), reverse=True)
>>> d_items_sorted
[(2, ('C', 11)), (3, ('D', 10)), (6, ('G', 5)), (5, ('F', 5)), (4, ('E', 5)), (1, ('B', 5)), (0, ('A', 5))]
This gives us the result we need, now turn it back into a dictionary
>>> {k: v for i, (k, v) in d_items_sorted}
{'C': 11, 'D': 10, 'G': 5, 'F': 5, 'E': 5, 'B': 5, 'A': 5}
Upvotes: 1