Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a dictionary in python by value when the value is a list and I want to sort it by the first index of that list

is it possible to sort a python dictionary by value if the value is a list, and I want it to be sorted by the first value of that list. E.G:

data = {
"Joe" : [1, "Joe", "password", "[email protected]"], 
"Toby" : [2, "Toby", "password", "[email protected]"], 
"John" : [4, "John", "password", "[email protected]"], 
"Julie" : [3, "Julie", "password", "[email protected]"]
}

I would like it to be like: Where 'i' is the key

for i in range(len(data)):
    print("UserID: ", str(data[i][0]), ". Username: ", data[i][1])

>> UserID: 1. Username: Joe
>> UserID: 2. Username: Toby
>> UserID: 3. Username: Julie
>> UserID: 4. Username: John

Many thanks.

like image 609
JoeTilsed Avatar asked Jan 05 '23 08:01

JoeTilsed


2 Answers

You cannot sort a dict in place, because Python dicts are unordered. You have at least 2 alternatives :

Create a sorted list of tuples

You can use sorted with a key= argument. In this case, it would be the first element of the dict value :

sorted(data.items(), key= lambda x: x[1][0])
# [('Joe', [1, 'Joe', 'password', '[email protected]']), ('Toby', [2, 'Toby', 'password', '[email protected]']), ('Julie', [3, 'Julie', 'password', '[email protected]']), ('John', [4, 'John', 'password', '[email protected]'])]

It returns a sorted list of tuples, which you can use to iterate and print the result :

data = {
    "Joe": [1, "Joe", "password", "[email protected]"],
    "Toby": [2, "Toby", "password", "[email protected]"],
    "John": [4, "John", "password", "[email protected]"],
    "Julie": [3, "Julie", "password", "[email protected]"]
}

for name, lst in sorted(data.items(), key=lambda x: x[1][0]):
    print("UserID : %d. Username : %s" % (lst[0], name))

# UserID : 1. Username : Joe
# UserID : 2. Username : Toby
# UserID : 3. Username : Julie
# UserID : 4. Username : John

Create an OrderedDict

If you want to sort data and keep the functionality of a dict, you can create an OrderedDict :

from collections import OrderedDict

data = {
    "Joe": [1, "Joe", "password", "[email protected]"],
    "Toby": [2, "Toby", "password", "[email protected]"],
    "John": [4, "John", "password", "[email protected]"],
    "Julie": [3, "Julie", "password", "[email protected]"]
}

data = OrderedDict(sorted(data.items(), key=lambda x: x[1][0]))
# OrderedDict([('Joe', [1, 'Joe', 'password', '[email protected]']), ('Toby', [2, 'Toby', 'password', '[email protected]']), ('Julie', [3, 'Julie', 'password', '[email protected]']), ('John', [4, 'John', 'password', '[email protected]'])])

Note : For both examples, key=lambda x: x[1] would also be enough.

like image 58
Eric Duminil Avatar answered Jan 13 '23 16:01

Eric Duminil


You can use itemgetter, this should sort the entries by the list (you can sort lists of lists and it will by default sort by the first element). This will give back a list of tuples, with the first element being the key, which you can loop through and print.

import operator

data = {
"Joe" : [1, "Joe", "password", "[email protected]"], 
"Toby" : [2, "Toby", "password", "[email protected]"], 
"John" : [4, "John", "password", "[email protected]"], 
"Julie" : [3, "Julie", "password", "[email protected]"]
}


sorted_data = sorted(data.items(), key=operator.itemgetter(1))

for entry in (sorted_data):
    print("UserID: " + str(entry[1][0]) + ". Username: " + entry[0])

Output:

UserID: 1. Username: Joe
UserID: 2. Username: Toby
UserID: 3. Username: Julie
UserID: 4. Username: John

Note: The reason sorted_data is a list of tuples instead of a dictionary is that python dictionaries are inherently unordered. See answers to this for an explanation: Why is python ordering my dictionary like so?

like image 33
Kewl Avatar answered Jan 13 '23 15:01

Kewl