When you create a dictionary in Python the order will not necessary be the order in which you create it. There is a solution for this and that is the use of an OrderedDict (can be found in the collections module).
Take the following example; you have a dictionary you want to use to classify an angle (0-360) into a cardinal direction. You define the dictionary, but if you print the dictionary directly afterwards you will notice that the order is not necessary the same as defined:
dctCard = {22.5:"E", 67.5: "NE", 112.5: "N",
157.5: "NW", 202.5: "W", 247.5: "SW",
292.5: "S", 337.5: "SE", 360: "E"}
print dctCard
results in:
>> {22.5: 'E', 67.5: 'NE', 247.5: 'SW', 202.5: 'W', 292.5: 'S', 112.5: 'N', 360: 'E', 337.5: 'SE', 157.5: 'NW'}
So if you would use code like below to obtain the cardinal direction based on an angle, this will give erroneous results:
dctCard = {22.5:"E", 67.5: "NE", 112.5: "N",
157.5: "NW", 202.5: "W", 247.5: "SW",
292.5: "S", 337.5: "SE", 360: "E"}
myangle = 75
for angle, cardinal in dctCard.items():
if myangle < angle:
result = cardinal
break
print "Angle {0} gives {1}".format(myangle, result)
could result in:
>> Angle 75 gives SW
Ordered dictionary
It is possible to solve this by using collections.OrderedDict(). Please be aware that the code below will still result in a randomly sorted dictionary:
from collections import OrderedDict
dctCard = OrderedDict({22.5:"E", 67.5: "NE", 112.5: "N",
157.5: "NW", 202.5: "W", 247.5: "SW",
292.5: "S", 337.5: "SE", 360: "E"})
The reason is, that first the dictionary is created in a random order and than that random order is stored as "ordered". There are two ways of solving this.
Either you loop through a sorted list of keys (the angle values):
dctCard = {22.5:"E", 67.5: "NE", 112.5: "N",
157.5: "NW", 202.5: "W", 247.5: "SW",
292.5: "S", 337.5: "SE", 360: "E"}
myangle = 75
for angle in sorted(dctCard.keys()):
if myangle < angle:
result = dctCard[angle]
break
Or you create a list of key value pairs and convert that to OrderedDict
from collections import OrderedDict
lstCardinal = [(22.5,"E"), (67.5, "NE"), (112.5, "N"),
(157.5, "NW"), (202.5, "W"), (247.5, "SW"),
(292.5, "S"), (337.5, "SE"), (360, "E")]
dctCard2 = OrderedDict(lstCardinal)
myangle = 75
for angle, cardinal in dctCard2.items():
if myangle < angle:
result = cardinal
break