I have a dictionary like this:
dict_str = {'Number_1_item':'foo',
'Number_11_item':'bar',
'Number_22_item':'foobar',
'Number_5_item':'barfoo'}
And my desired out put is:
sorted_dict_str = {'Number_1_item':'foo',
'Number_5_item':'bar',
'Number_11_item':'foobar',
'Number_22_item':'barfoo'}
So the sorted_dict_str is sorted in numerical way based on the keys in dict_str. I have found some answers to sort the keys with pure numeric keys but not mixed ones, so they are not really helpful.
Thanks a lot.
Regards
Yet another solution. When executing the sorted function it'll return a sorted list of all the keys in the dictionary. A dictionary can't be sorted (though there is a way of having an ordered dictionary ).
This Solution is also more robust compared to the first solution, since the number can be anywhere in the key.
import re
from collections import OrderedDict
d = {'Number_1_item':'foo',
'Number_11_item':'bar',
'Number_22_item':'foobar',
'Number_5_item':'barfoo'}
keys = d.keys()
def sort_mixed(key):
int_match = re.search(r'(?P<int>\d+)', key)
number = int_match.group(0)
return int(number)
sorted_keys = sorted(keys, key=lambda key: sort_mixed(key))
print(sorted_keys) # print sorted keys
sorted_dict = OrderedDict((k, d[k]) for k in sorted_keys)
print(sorted_dict) # print new sorted dict
You can get sorted dict from your dict like that:
from collections import OrderedDict
OrderedDict(sorted(dict_str.items(), key=lambda s: int(s[0].split('_')[1])))
If we can assume that all the keys are on the format Number_XX_item
, you could simply sort on the numeric part, using a lambda:
sorted_dict_str = sorted(dict_str.items(), key=lambda x: int(x[0].split('_')[1]))
This gives the following output:
sorted_dict_str =
[('Number_1_item', 'foo'),
('Number_5_item', 'barfoo'),
('Number_11_item', 'bar'),
('Number_22_item', 'foobar')]
You should check out natsort . There are ways to do it by yourself, without importing extra modules, but I like is method.
>>> from collections import OrderedDict
>>> import natsort
>>> input_dict = {'Number_1_item':'foo', 'Number_11_item':'bar', 'Number_22_item':'foobar', 'Number_5_item':'barfoo'}
>>> OrderedDict(natsort.natsorted(input_dict.items()))
OrderedDict([('Number_1_item', 'foo'), ('Number_5_item', 'barfoo'), ('Number_11_item', 'bar'), ('Number_22_item', 'foobar')])
Here's a solution using the slicing technique I mentioned in the comments. This is less robust than using .split
, since the lengths of the prefix & suffix strings are hard-coded, but it's slightly faster because slicing is fast compared to a method call.
from collections import OrderedDict
from pprint import pprint
dict_str = {
'Number_1_item':'foo',
'Number_11_item':'bar',
'Number_22_item':'foobar',
'Number_5_item':'barfoo',
}
skeys = sorted(dict_str.keys(), key=lambda s: int(s[7:][:-5]))
sorted_dict = OrderedDict((k, dict_str[k]) for k in skeys)
pprint(sorted_dict)
output
OrderedDict([('Number_1_item', 'foo'),
('Number_5_item', 'barfoo'),
('Number_11_item', 'bar'),
('Number_22_item', 'foobar')])
You could also do the sorting on the (key, value) pairs inside the OrderedDict
constructor call:
sorted_dict = OrderedDict(sorted(dict_str.items(), key=lambda u: int(u[0][7:][:-5])))
but I think my previous version is a little more readable.
You can't sort the dict itself by definition of what a dict is. But you can sort its keys in any custom order by passing the desired 'key' argument into sorted function
sorted(iterable[, cmp[, key[, reverse]]])
You can sort the keys of a dictionary into a list, with the additional key-Argument:
dict_str = {'Number_1_item':'foo',
'Number_11_item':'bar',
'Number_22_item':'foobar',
'Number_5_item':'barfoo'}
sorted_keys = sorted(dict_str, key=lambda x: int(x.split('_')[1]))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.