Converting dict to OrderedDict

Question:

I am having some trouble using the collections.OrderedDict class. I am using Python 2.7 on Raspbian, the Debian distro for Raspberry Pi. I am trying to print two dictionaries in order for comparison (side-by-side) for a text-adventure. The order is essential to compare accurately.
No matter what I try the dictionaries print in their usual unordered way.

Here’s what I get when I do it on my RPi:

import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

Obviously there is something not right because it is printing the function call and putting the keys and value groups into a nested list…

This is what I got by running something similar on my PC:

import collections

Joe = {"Age": 28, "Race": "Latino", "Job": "Nurse"}
Bob = {"Age": 25, "Race": "White", "Job": "Mechanic", "Random": "stuff"}

#Just for clarity:
Joe = collections.OrderedDict(Joe)
Bob = collections.OrderedDict(Bob)

print Joe
# OrderedDict([('Age', 28), ('Race', 'Latino'), ('Job', 'Nurse')])
print Bob
# OrderedDict([('Age', 25), ('Race', 'White'), ('Job', 'Mechanic'), ('Random', 'stuff')])

This time, it is in order, but it shouldn’t be printing the other things though right? (The putting it into list and showing function call.)

Where am I making my error? It shouldn’t be anything to do with the pi version of Python because it is just the Linux version.

Asked By: ninthpower

||

Answers:

You are creating a dictionary first, then passing that dictionary to an OrderedDict. For Python versions < 3.6 (*), by the time you do that, the ordering is no longer going to be correct. dict is inherently not ordered.

Pass in a sequence of tuples instead:

ship = [("NAME", "Albatross"),
        ("HP", 50),
        ("BLASTERS", 13),
        ("THRUSTERS", 18),
        ("PRICE", 250)]
ship = collections.OrderedDict(ship)

What you see when you print the OrderedDict is it’s representation, and it is entirely correct. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)]) just shows you, in a reproducable representation, what the contents are of the OrderedDict.


(*): In the CPython 3.6 implementation, the dict type was updated to use a more memory efficient internal structure that has the happy side effect of preserving insertion order, and by extension the code shown in the question works without issues. As of Python 3.7, the Python language specification has been updated to require that all Python implementations must follow this behaviour. See this other answer of mine for details and also why you’d still may want to use an OrderedDict() for certain cases.

Answered By: Martijn Pieters

Most of the time we go for OrderedDict when we required a custom order not a generic one like ASC etc.

Here is the proposed solution:

import collections
ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship


new_dict = collections.OrderedDict()
new_dict["NAME"]=ship["NAME"]
new_dict["HP"]=ship["HP"]
new_dict["BLASTERS"]=ship["BLASTERS"]
new_dict["THRUSTERS"]=ship["THRUSTERS"]
new_dict["PRICE"]=ship["PRICE"]


print new_dict

This will be output:

OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])
OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

Note: The new sorted dictionaries maintain their sort order when entries are deleted. But when new keys are added, the keys are appended to the end and the sort is not maintained.(official doc)

Answered By: Abdul Majeed

If you can’t edit this part of code where your dict was defined you can still order it at any point in any way you want, like this:

from collections import OrderedDict

order_of_keys = ["key1", "key2", "key3", "key4", "key5"]
list_of_tuples = [(key, your_dict[key]) for key in order_of_keys]
your_dict = OrderedDict(list_of_tuples)
Answered By: Jan Rozycki

Use dict.items(); it can be as simple as following:

ship = collections.OrderedDict(ship.items())
Answered By: Mehmet

You can create the ordered dict from old dict in one line:

from collections import OrderedDict
ordered_dict = OrderedDict(sorted(ship.items())

The default sorting key is by dictionary key, so the new ordered_dict is sorted by old dict’s keys.

Answered By: Random Certainty

Hoping this serves as an alternative answer. Cheers!


import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

# unsequenced key value pair in the dict
print ship

# before using inherent dict for creating an OrderedDict
print collections.OrderedDict(ship)
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

list_key = ["NAME","HP","BLASTERS","THRUSTERS","PRICE"]
ordered_list = [(key,ship[key]) for key in list_key]
ordered_ship = collections.OrderedDict(ordered_list)

print ordered_ship
# OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

Answered By: dhruv sharma
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.