How to change the order of keys in a Python 3.5 dictionary, using another list as a reference for keys?

Question:

I’m trying to change the order of ‘keys’ in a dictionary, with no success.
This is my initial dictionary:

Not_Ordered={
  'item':'book',
  'pages':200, 
  'weight':1.0, 
  'price':25, 
  'city':'London'
}

Is there a chance for me to change the order according to a key-order list, like this:

key_order=['city', 'pages', 'item', 'weight', 'price']

note:

  • I’m using Python 3.5.2.
  • I’m not looking for sorting the keys.
  • I’m aware that Python 3.6 follows the insertion.
  • Also, I’m aware of OrderedDict, but it gives me a list, but I’m
    looking for a dictionary as final result.
Asked By: Behrouz Beheshti

||

Answers:

Your problem here is that prior to Python 3.7 dictionaries did not have an insertion order so you could not "order" them. As you can see here: Official Python Docs on Dictionaries.
If you provide more insight on whats the purpose of this we might try to solve it in other way.

Answered By: A.Lorefice

Dicts are “officially” maintained in insertion order starting in 3.7. They were so ordered in 3.6, but it wasn’t guaranteed before 3.7. Before 3.6, there is nothing you can do to affect the order in which keys appear.

But OrderedDict can be used instead. I don’t understand your “but it gives me a list” objection – I can’t see any sense in which that’s actually true.

Your example:

>>> from collections import OrderedDict
>>> d = OrderedDict([('item', 'book'), ('pages', 200),
...                  ('weight', 1.0), ('price', 25),
...                  ('city', 'London')])
>>> d # keeps the insertion order
OrderedDict([('item', 'book'), ('pages', 200), ('weight', 1.0), ('price', 25), ('city', 'London')])
>>> key_order= ['city', 'pages', 'item', 'weight', 'price'] # the order you want
>>> for k in key_order: # a loop to force the order you want
...     d.move_to_end(k)
>>> d # which works fine
OrderedDict([('city', 'London'), ('pages', 200), ('item', 'book'), ('weight', 1.0), ('price', 25)])

Don’t be confused by the output format! d is displayed as a list of pairs, passed to an OrderedDict constructor, for clarity. d isn’t itself a list.

Answered By: Tim Peters

no solution in Python 3.5


for python >= 3.6, just

Ordered_Dict = {k : Not_Ordered_Dict[k] for k in key_order}
Answered By: Chang Ye

you still can use sorted and specify the items().

ordered_dict_items = sorted(Not_Ordered.items(), key=lambda x: key_order.index(x[0]))  
return dict((x, y) for x, y in ordered_dict_items) # to convert tuples to dict

or directly using lists:

ordered_dict_items = [(k, Not_Ordered[k]) for k in key_order]
return dict((x, y) for x, y in ordered_dict_items) # to convert tuples to 
Answered By: 0x2bad
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.