Reorder dictionary in python according to a list of values

32,712

Solution 1

Answer for Python 3.6+

Guido has assured dictionaries would be ordered from Python 3.7 onwards, and they already were as an experimental feature in 3.6. The answer has already been expanded on in Fastest way to sort a python 3.7+ dictionary.

In this case, building a new dict with simple dictionary comprehension based on the items contained in the desired_order_list will do the trick.

sample_dict = {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}
print(sample_dict)
>>> {1: 'r099', 2: 'g444', 3: 't555', 4: 'f444', 5: 'h666'}

desired_order_list = [5, 2, 4, 3, 1]

reordered_dict = {k: sample_dict[k] for k in desired_order_list}
print(reordered_dict)
>>> {5: 'h666', 2: 'g444', 4: 'f444', 3: 't555', 1: 'r099'}

Solution 2

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 your ordered dict in the sequence you want, such that later you can do

my_ordered_dict.values()

And get the list you suggested in the question.

If you wrap the reinsertion in a try: ...; except KeyError: pass, you can reorder an OrderedDict even if not all the keys in your list are present.

Solution 3

Python dictionaries are unordered.

Use OrderedDict instead.

Solution 4

What is the meaning of reordering the dictionary for you? Dictionaries are unordered data structures by their nature - they are used for lookup rather than order.

Do you want to iterate over the dictionary in some specific order? Then just use your desired_order_list:

for key in desired_order_list: 
  # d is the dictionary
  # do stuff with d[key]

As others have mentioned, Python has an OrderedDict (in 2.7 or 3.x), but I don't think it's what you need here. "Reordering" it is just too inefficient. It's much better to just carry your dictionary along with the list of keys in desired order, together.

If you still insist on an OrderedDict, just create a new OrderedDict, inserting the value into it in the order of desired_order_list.

Solution 5

Using an OrderedDict or Eli's solution will probably be a good way to go, but for reference here is a simple way to obtain the list of values you want:

[sample_dict[k] for k in desired_order_list]

If you aren't completely sure that every element from desired_order_list will be a key in sample_dict, use either [sample_dict.get(k) ...] or [... for k in desired_order_list if k in sample_dict]. The first method will put None in for missing keys, the second method will only include values from the keys are are in the dict.

Share:
32,712

Related videos on Youtube

user699540
Author by

user699540

Updated on July 09, 2022

Comments

  • user699540
    user699540 almost 2 years

    Let us consider a dictionary:

    sample_dict={1:'r099',2:'g444',3:'t555',4:'f444',5:'h666'}
    

    I want to re-order this dictionary in an order specified by a list containing the order of the dictionary keys that I desire. Let us say the desired order list is:

    desired_order_list=[5,2,4,3,1]
    

    So, I want my dictionary to appear like this:

    {5:'h666',2:'g444',4:'f444',3:'t555',1:'r099'}
    

    If I can get a list of values that is fine too. Meaning, the result can be this:

    ['h666','g444','f444','t555','r099']
    

    How do I achieve this in the least complex way possible?

    • jscs
      jscs almost 13 years
      Are you actually using a collections.OrderedDict?
    • user699540
      user699540 almost 13 years
      Should I use something like this: OrderedDict(sorted(sample_dict.items(), key=lambda t: [5,2,4,3,1])
  • user699540
    user699540 almost 13 years
    Okay, but how do I re-order them in a specific order ?
  • user699540
    user699540 almost 13 years
    I use Activestate Python and SortedDict package is unavailable in PyPm (code.activestate.com/pypm/sorteddict)
  • Imran
    Imran almost 13 years
    Just copy/paste the implementation from django source http://code.djangoproject.com/browser/django/trunk/django/ut‌​ils/datastructures.p‌​y#L99. Django is BSD licensed, so even if your application is commercial you'll be fine.