AMisra
AMisra

Reputation: 1889

sort a list of dictionary by taking integer value of keys stored as string

I have a list of dictionaries with values stored as strings. I want to sort them by taking the values as integer not string. Code I have

 XWordDict=[{"name":"ABC","pos":"1"},{"name":"GHI","pos":"10"},{"name":"DEF","pos":"2"}]
Xlistsorted=sorted(XWordDict,key=(operator.itemgetter("pos")))

This gives the order as

[{'name': 'ABC', 'pos': '1'}, {'name': 'GHI', 'pos': '10'}, {'name': 'DEF', 'pos': '2'}]

however I want it to be

 [{'name': 'ABC', 'pos': '1'}, {'name': 'DEF', 'pos': '2'}, {'name': 'GHI', 'pos': '10'}]

If I change to

Xlistsorted=sorted(XWordDict,key=int(operator.itemgetter("pos)))

it gives an error

TypeError: int() argument must be a string or a number, not 'operator.itemgetter'

Upvotes: 3

Views: 7497

Answers (2)

penryu
penryu

Reputation: 130

The argument to sorted()'s "key" keyword is a unary function that returns the actual value you want sorted. So you'll need a function that converts each element of the list (the dictionary which we'll call d), accesses the value you want to sort on, and converts it from a string to an integer.

def dict_to_int(d):
    string_value = d['pos']
    int_value = int(string_value)
    return int_value

You would pass this to sorted() like this:

sorted_list = sorted(list_of_dicts, key=dict_to_int)

This function is a verbose example, and can be shortened significantly and converted to a fairly concise lambda:

lambda d: int(d['pos'])

and used thus:

sorted_list = sorted(list_of_dicts, key=lambda d: int(d['pos']))

Upvotes: 3

Marius
Marius

Reputation: 60060

The key argument needs to be a function. operator.itemgetter(i) returns a function, but in order to add extra processing on top of that, you'll have to use a lambda. Because itemgetter returns a function, you can call the result to use it on the dictionary (which you are passing as the x in the lambda:

listsorted = sorted(XWordDict, key=lambda x: int(operator.itemgetter("pos")(x)))
listsorted
Out[16]: 
[{'name': 'ABC', 'pos': '1'},
 {'name': 'DEF', 'pos': '2'},
 {'name': 'GHI', 'pos': '10'}]

That said, itemgetter might be an overly complex solution here, you can just do:

listsorted = sorted(XWordDict, key=lambda x: int(x['pos']))

Upvotes: 10

Related Questions