Seetharama
Seetharama

Reputation: 149

Sorting Keys in a Dictionary with multiple decimal points and String in Python

I am using Python 3.5. I have a dictionary with entries:

myresult = { '6.1.2 & 6.3.2, abcd' : xyz, 
             '6.10.2 & 6.12.2, hjsd' : xyz, abc, ssd
             '6.2.2 & 6.4.2, abcd' : asd,
             '6.9.2 & 6.11.2, qwer' : tzu, 
             '6.21.2 & 6.23.2, xzty' : asd }

Expected output is

>>>'6.1.2 & 6.3.2, abcd' : xyz
   '6.2.2 & 6.4.2, abcd' : asd
   '6.9.2 & 6.11.2, qwer' : tzu,
   '6.10.2 & 6.12.2, hjsd' : xyz, abc, ssd
   '6.21.2 & 6.23.2, xzty' : asds

i.e., I need the numbers to be sorted after the decimal point as normal integers.

I tried using for key in sorted(myresult.keys()): print(key)

The output was

'6.1.2 & 6.3.2, abcd' : xyz
'6.10.2 & 6.12.2, hjsd' : xyz, abc, ssd
'6.2.2 & 6.4.2, abcd' : asd
'6.21.2 & 6.23.2, xzty' : asds
'6.9.2 & 6.11.2, qwer' : tzu

Any Help would be very much appreciated.

Thank you

Upvotes: 2

Views: 403

Answers (1)

L3viathan
L3viathan

Reputation: 27283

A simple way to achieve that is to supply a key function to sorted:

def num_keyfn(something):
    parts = something.split(".")
    return tuple(int(x) if x.isnumeric() else x for x in parts)

for key in sorted(myresult.keys(), key=num_keyfn):
    print(key)

This prints:

6.1.2 & 6.3.2, abcd
6.2.2 & 6.4.2, abcd
6.9.2 & 6.11.2, qwer
6.10.2 & 6.12.2, hjsd
6.21.2 & 6.23.2, xzty

This is not perfect yet, as it won't work if the difference is in the middle somewhere, but you can see the principle and adapt it to your needs.


When sorted (or .sort) is given a key function, instead of comparing elements directly, it will first call this function on the element. For example, to sort strings by length, you can supply the argument key=len.

Python can compare tuples: (2,4) is smaller than (2,5).

In my answer, I split the strings on every dot into parts, and cast to int any part that .isnumeric(). While "10" is smaller than "2", 10 is not smaller than 2.

Upvotes: 2

Related Questions