How to rearrange an Ordered Dictionary with a based on part of the key from a list

ordered dictionary python
python sort dictionary by value descending
python sort dictionary of dictionaries by value
sort dictionary by value python 3
python sort dictionary of dictionaries by key
python sort list of dictionaries multiple keys
sort dictionary by value then key python
python sort by key

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.

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)])

Reorder dictionary in python according to a list of values, If you're using an OrderedDict , you can do for key in [5,2,4,3,1]: my_ordered_dict[ key] = my_ordered_dict.pop(key). This reinserts everything in� To sort dictionary elements by value we will use the same sorted () function and pass a key function that will return the 1th index element of tuple i.e. the value field from the key/value pair, # Create a list of tuples sorted by index 1 i.e. value field listofTuples = sorted(wordsFreqDict.items(), key=lambda x: x)

You can build a dict that maps each item in order to its index, and then use the sorted function with a key function that maps the substring of the each key in old_OD that appears in the keys of the mapping dict to the corresponding index using the mapping dict:

keys = {k: i for i, k in enumerate(order)}
OrderedDict(sorted(old_OD.items(), key=lambda t: keys.get(next(i for i in t[0].split('_') if i in keys))))

This returns:

OrderedDict([('dog_1', 2), ('dog_2', 5), ('cat_1', 1), ('cat_2', 3), ('fish_1', 4)])

How could reorder the keys in the dictionary? - Scripting, How could I reorder the key part to NewDict = {(0, 1): (2.733), (0, Then you should get a sorted list of keys based on running the sorted� 1. 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.

Here is another approach using regex and partial functions.

import re
from operator import itemgetter
from functools import partial

first = itemgetter(0)
pattern = '|'.join(order) # 'dog|cat|fish'

def group(order, pattern, txt):
    item = first(txt)
    res = re.search(pattern, item)
    return order.index(res.group(0))

p = partial(group, order, pattern)

OrderedDict(sorted(old_OD.items(), key=p))

OrderedDict([('dog_1', 2),
             ('dog_2', 5),
             ('cat_1', 1),
             ('cat_2', 3),
             ('fish_1', 4)])

OrderedDict — Remember the Order Keys are Added to a Dictionary , An OrderedDict is a dictionary subclass that remembers the order in values in order based on how the keys are stored in the hash table, dict does track insertion order, although this behavior is a side-effect of move the item to be the last item in the key sequence (when True ) or the first (when False ). Since dictionary is a collection of randomly arranged pair of key and value you can not actually sort a dictionary itself but yes you can have a sorted view of the dictionary. Possibly a list generated from the entries in a dictionary.

You can use the function groupby() with a sorted dictionary:

from collections import OrderedDict
from itertools import groupby, chain
from operator import itemgetter

ld_OD = OrderedDict([('cat_1',1), 
    ('dog_1',2), 
    ('cat_2',3),
    ('fish_1',4), 
    ('dog_2',5)])

order = ['dog', 'cat', 'fish']

gb = groupby(sorted(ld_OD.items()), key=lambda t: t[0].split('_')[0])
gb = {k: list(g) for k, g in gb}
OrderedDict(chain.from_iterable(itemgetter(*order)(gb)))
# OrderedDict([('dog_1', 2), ('dog_2', 5), ('cat_1', 1), ('cat_2', 3), ('fish_1', 4)])

Python, Python - Sort list of Single Item dictionaries according to custom ordering � Ways to sort list of dictionaries by values in Python - Using lambda� # d is your old dictionary sortedkeys = sorted(d.keys(), key=lambda x,y:x*10000+y) current_x = -1 current_y = 0 row = None new_d = {} for key in sortedkeys: x,y = key if x != row: row = x current_x = current_x + 1 current_y = 0 else: current_y = current_y + 1 new_d[(current_x, current_y)] = d[key]

A more efficient approach to solve this problem in a time complexity of O(n) (instead of O(n log n) with sorting) is to build a dict that maps the substring of each key that appears in order (which should be converted to a set for efficient lookups) to a list of belonging key-value pairs from old_OD, and then build the new OrderedDict by iterating an index through a range of the length of order and output to the OrderedDict constructor the values in the mapping dict keyed by the value of order at the index:

keys = set(order)
mapping = {}
for k, v in old_OD.items():
    mapping.setdefault(next(i for i in k.split('_') if i in keys), []).append((k, v))
OrderedDict(t for i in range(len(order)) for t in mapping[order[i]])

This returns:

OrderedDict([('dog_1', 2), ('dog_2', 5), ('cat_1', 1), ('cat_2', 3), ('fish_1', 4)])

Python : How to Sort a Dictionary by key or Value ? – thispointer.com, So list of tuples (key / value pairs) is sorted by keys. Now we can iterate over this sort list of tuple i.e. all sorted keys value pairs from dictionary� It is possible to change the order of the keys in an OrderedDict by moving them to either the beginning or the end of the sequence using move_to_end().

How to Sort a Dictionary by Value in Python, Python's built-in sorted() function can be used to sort iterable objects by a key, such as lists, tuples, and dictionaries. The sorted() function sorts� Python | Sort nested dictionary by key Sorting has quite vivid applications and sometimes, we might come up with the problem in which we need to sort the nested dictionary by the nested key. This type of application is popular in web development as JSON format is quite popular.

Dicts are now ordered, get used to it, Changed in version 3.7: Dictionary order is guaranteed to be Does it mean that a dict with int keys is the same as list? I glossed over the "insertion order" part. The behavior of the set type is based on the mathematical idea that two which they do not need to move memory and simply call append()). The position of each key in the list should determine the position in the sorted dictionary. If a key has a lower position in the list, the position in the dictionary should be lower as well. If a key is not in the list, just put it on the bottom of the dictionary. Converted into code, it will look like this.

Sort a Python Dictionary by Value or Key, In Python versions 3.5 and earlier dictionaries cannot store items in an ordered manner like lists or tuples. However, it is possible to create a� Dim myOrderedDictionary As New OrderedDictionary() myOrderedDictionary.Add("testKey1", "testValue1") myOrderedDictionary.Add("testKey2", "testValue2") myOrderedDictionary.Add("keyToDelete", "valueToDelete") myOrderedDictionary.Add("testKey3", "testValue3") Dim keyCollection As ICollection = myOrderedDictionary.Keys Dim valueCollection As ICollection = myOrderedDictionary.Values ' Display the contents Imports the key and value collections DisplayContents( _ keyCollection, valueCollection

Comments
  • Great first question! I wish all new contributors were like you!
  • If the input is OrderedDict([('dog_2', 2), ('dog_1', 1)]), would the desired output be OrderedDict([('dog_1', 1), ('dog_2', 2)]) (sort by number) or OrderedDict([('dog_2', 2), ('dog_1', 1)]) (maintain the original order)?
  • Hmm, this doesn't sort the keys by the numbers, though. (For example, an input of {'dog_2': 5, 'dog_1': 2} would not change at all.) Not sure if that's what the OP wants.
  • @Aran-Fey It is ok if it is not sorted in numerical or alphabetical order, as long as it is in group.
  • @Aran-Fey It was a fair point. I added the variant of the solution with lexicographical sorting
  • @Bogdan Please add that piece of information to your question.
  • 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. Thanks!
  • I see. I've updated both of my answers accordingly then.