1

I would like to rank the values in a dictionary.

For instance, I have this dictionary: {"A": 10, "B: 3, "C": 8, "D": 3, "E": 2} The result should look like: {"E": 1, "B": 2, "D": 2, "C": 4, "A": 5}

Please note that D is ranked as fourth because B and D are tied at position two. Hence, there is no position three.

Similar solutions have already been given in other threads, however they did not take into account ex-aequo positions in the traditional way: Adding a rank to a dict in python and Python Ranking Dictionary Return Rank

Community
  • 1
  • 1
beta
  • 5,324
  • 15
  • 57
  • 99
  • You want to sort the dict by its values, and then use the sorted indices (+1) as ranking? Well, with the ex-aequo caveat of course. –  Oct 02 '15 at 13:48
  • hm yes. sort of. but how about ties to achieve the expected result given above (when two have the same value and position)? it seems not trivial to me. – beta Oct 02 '15 at 13:49

1 Answers1

3

First sort the data in ascending order based on the number, like this

>>> data = {"A": 10, "B": 3, "C": 8, "D": 3, "E": 2}
>>> s_data = sorted(data.items(), key=lambda item: item[1])
>>> s_data
[('E', 2), ('D', 3), ('B', 3), ('C', 8), ('A', 10)]

Now, for every element processed,

  • if it is not the same as the previous element then the rank should be incremented by the number of similar elements processed till now

  • if it is the same, then simply count the current element as a similar element

To implement this, initialize few variables, like this

>>> rank, count, previous, result = 0, 0, None, {}

then keep checking if the current element is not equal to the previous element and if it is true, increment rank by the number of times the similar elements occured.

>>> for key, num in s_data:
...     count += 1
...     if num != previous:
...         rank += count
...         previous = num
...         count = 0
...     result[key] = rank

Now, result will have the result you wanted.

>>> result
{'D': 2, 'C': 4, 'E': 1, 'B': 2, 'A': 5}
thefourtheye
  • 233,700
  • 52
  • 457
  • 497