1

I have a dictionary where the values are floating point numbers. I am trying to sort the dictionary in decreasing order of values and I am trying to break ties by sorting the keys in ascending order.

I implemented the following code to achieve this:

for key, value in sorted(dictionary.items(), key=lambda x: (-x[1], x[0])):

    print key, value

Some of my values seem out of place.

2315 0.000232471518033

2823 0.000232414850716

3649 0.00023239634392

3695 0.00023239634392

3883 0.00023239634392

3479 0.00023239634392

3562 0.00023239634392

3613 0.00023239634392

As per the above code line starting with 3479 should be printed before the line starting with 3649.

Any ideas on what might be wrong with the way I have sorted the dictionary? Has it got anything to do with the precision of floating point numbers?

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
warun26
  • 453
  • 9
  • 18
  • Read this http://stackoverflow.com/questions/9001509/how-can-i-sort-a-dictionary-by-key – grael Oct 12 '15 at 07:53
  • Possible duplicate of [Sort a Python dictionary by value](http://stackoverflow.com/questions/613183/sort-a-python-dictionary-by-value) – Mp0int Oct 12 '15 at 07:59
  • @grael OP is sorting by value, or rather lexicographically by `(value, key)` – dhke Oct 12 '15 at 07:59
  • 1
    What makes you think the order is *wrong*? `float`s are not *displayed* with full precision by default, hence it may *seem* that both numbers are equal, when they need not be. If you want them truncated to a certain precision, do so: `lambda x: (-round(x[1], 14), x[0])`, manually. – dhke Oct 12 '15 at 08:01
  • Print the numbers with something like print("{} {:.16f}".format(key, value)) to see more precision. – RemcoGerlich Oct 12 '15 at 08:03
  • @dhke: Thanks for the suggestion. The results I was getting was because floats are not displayed with full precision by default. – warun26 Oct 12 '15 at 08:31

2 Answers2

7

Has it got anything to do with the precision of floating point numbers?

Yes.

>>> 0.0002323963439201
0.0002323963439201
>>> print 0.0002323963439201
0.00023239634392
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • No it is not about precision. Python `dict`ionaries are unordered. – Mp0int Oct 12 '15 at 07:58
  • @FallenAngel: You *did* see the part where `sorted()` was called, right? – Ignacio Vazquez-Abrams Oct 12 '15 at 07:59
  • @FallenAngel dictionaries aren't ordered, but the result of `sorted` is – jonrsharpe Oct 12 '15 at 07:59
  • Ah sorry, missed that part. Need one more cup of coffee. – Mp0int Oct 12 '15 at 08:00
  • you will get my upvote if you add what should be done to change this – The6thSense Oct 12 '15 at 08:01
  • @VigneshKalai: At this point what *should* be done is a matter of opinion. There are two possible ways to fix it, and there is not enough context in the question to choose between the two. – Ignacio Vazquez-Abrams Oct 12 '15 at 08:02
  • Thanks for the answer @IgnacioVazquez-Abrams. It helped me understand the results I was getting. Just for discussion's sake, the context is that the above mentioned values are page rank scores for nodes(the keys in the dictionary are an identifier I have assigned to the different nodes). I was trying to sort the nodes in decreasing order of page rank scores to find which nodes are central to the network/graph I have. – warun26 Oct 12 '15 at 08:36
0

I think you are ordering with respect to the wrong components of the dictionary. You can just do:

for key, value in sorted(dictionary.items(), key=lambda x: (x[0]):
print key, value

if you want to order per key, and

for key, value in sorted(dictionary.items(), key=lambda x: (-x[1]):
print key, value

if you want to order per value.

Helios83
  • 87
  • 1
  • 12