How do I sort the particular list of dictionary first on the basis of their Units (bit/s, Kbit/s, etc) and then sort them according to their value

Viewed 54
my_lst = [
        {"usage": "0.59 Kbit/s"},
        {"usage": "383.34 bit/s"},
        {"usage": "158.13 bit/s"},
        {"usage": "4.15 Gbit/s"},
        {"usage": "18.5 Mbit/s"},
        {"usage": "45 Kbit/s"}
    ]

The output trying to achieve should be something like this with sorted value:-

my_lst = [
    {'usage': '4.15 Gbit/s'}, 
    {'usage': '18.5 Mbit/s'}, 
    {'usage': '45 Kbit/s'}, 
    {'usage': '0.59 Kbit/s'}, 
    {'usage': '383.34 bit/s'}, 
    {'usage': '158.13 bit/s'}
]
3 Answers

Oneway using humanfriendly.parse_size:

from humanfriendly import parse_size

sorted(my_lst, key=lambda x: parse_size(x["usage"]), reverse=True)

Output:

[{'usage': '4.15 Gbit/s'},
 {'usage': '18.5 Mbit/s'},
 {'usage': '45 Kbit/s'},
 {'usage': '0.59 Kbit/s'},
 {'usage': '383.34 bit/s'},
 {'usage': '158.13 bit/s'}]

You could use the humanfriendly module:

from humanfriendly import parse_size
print(sorted(my_lst, key=lambda x: parse_size(x["usage"])[::-1])

The other answers that uses the humanfriendly library is the better solution. Here is just an alternative without using a library.

from decimal import Decimal

UNIT_MAPPINGS = {
    "": 1,
    "K": pow(10, 3),
    "M": pow(10, 6),
    "G": pow(10, 9),
}

my_lst = [
    {"usage": "0.59 Kbit/s"},
    {"usage": "383.34 bit/s"},
    {"usage": "158.13 bit/s"},
    {"usage": "4.15 Gbit/s"},
    {"usage": "18.5 Mbit/s"},
    {"usage": "45 Kbit/s"}
]

def convert_rate(rate):
    num, _, unit = rate['usage'].partition(" ")
    unit = unit.replace('bit/s', '')
    return Decimal(num) * UNIT_MAPPINGS[unit]

my_lst.sort(key=convert_rate, reverse=True)
print(my_lst)

Output

[{'usage': '4.15 Gbit/s'}, {'usage': '18.5 Mbit/s'}, {'usage': '45 Kbit/s'}, {'usage': '0.59 Kbit/s'}, {'usage': '383.34 bit/s'}, {'usage': '158.13 bit/s'}]
Related