I am rearranging some Ordered Dictionary based on the key from a list. Such in:
old_OD = OrderedDict([('cat_1',1),
('dog_1',2),
('cat_2',3),
('fish_1',4),
('dog_2',5)])
Now I have a list of the group's order.
order = ['dog', 'cat', 'fish']
and get the result with the items in the dictionary grouped together, as such:
new_OD = OrderedDict([('dog_1',2),
('dog_2',5),
('cat_1',1),
('cat_2',3),
('fish_1',4)])
I found some excellent related question How to reorder OD based on list and Re-ordering OrderedDict and I am going with the solution in the second link
new_od = OrderedDict([(k, None) for k in order if k in old_od])
new_od.update(old_od)
Now, in my case, "k" is not exact match and desired key value for the new_od, how should I modify to construct the new od?
EDIT: So what happen if there is no underscore that mark the location of the keyword, like we have "Big_cat_3" or "dog_black_2"? The keyword could be anywhere in the string. Once the key are grouped together, alpha-numerical order is not needed.
To sort a dictionary by value in Python you can use the sorted() function. Python's sorted() function can be used to sort dictionaries by key, which allows for a custom sorting method. sorted() takes three arguments: object, key, and reverse . Dictionaries are unordered data structures.
OrderedDicts are ordered by insertion order. So you would have to construct a new OrderedDict by looping over the key:value pairs in the original object. There is no OrderedDict method that will help you.
Dicts can't be sorted, but you can build a sorted list from them.
Here I am sharing two variants of solution for this.
1. For keys with same prefix, keep the order of initial OrderedDict
Here I am using list comprehension to iterate the order
list and OrderDict
. Based on comparison, we are passing list of tuples with desired order for creating OrderedDict
object:
>>> from collections import OrderedDict
>>> old_OD = OrderedDict([('cat_1',1),
... ('dog_1',2),
... ('cat_2',3),
... ('fish_1',4),
... ('dog_2',5)])
>>> order = ['dog', 'cat', 'fish']
>>> new_OD = OrderedDict([(k,v) for o in order for k, v in old_OD.items() if k.startswith(o+'_')])
# to match the prefix pattern of <key> + "_" ^
where new_OD
will hold:
OrderedDict([('dog_1', 2), ('dog_2', 5), ('cat_1', 1), ('cat_2', 3), ('fish_1', 4)])
2. For keys with same prefix, perform lexicographical sorting of elements
We may modify the above solution using sorted
and itertools.chain
with nested list comprehension to achieve this as:
>>> from itertools import chain
>>> new_OD = OrderedDict(chain(*[sorted([(k,v) for k, v in old_OD.items() if k.startswith(o+'_')]) for o in order]))
where new_OD
will hold:
OrderedDict([('dog_1', 2), ('dog_2', 5), ('cat_1', 1), ('cat_2', 3), ('fish_1', 4)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With