4
"""Ordered dictionary class, from a Python Cookbook recipe:
6
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/107747
11
from UserDict import UserDict
13
class Odict (UserDict):
14
def __init__(self, keys=None, values=None):
15
"""Create an Odict from the given keys and values."""
18
if len(keys) != len(values):
19
raise ValueError("keys and values are not the same length")
21
UserDict.__init__(self, dict(zip(keys, values)))
23
def __delitem__(self, key):
24
UserDict.__delitem__(self, key)
25
self._keys.remove(key)
27
def __setitem__(self, key, item):
28
UserDict.__setitem__(self, key, item)
29
if key not in self._keys: self._keys.append(key)
36
dict = UserDict.copy(self)
37
dict._keys = self._keys[:]
41
return zip(self._keys, self.values())
50
raise KeyError('dictionary is empty')
57
def setdefault(self, key, failobj = None):
58
UserDict.setdefault(self, key, failobj)
59
if key not in self._keys: self._keys.append(key)
61
def update(self, dict):
62
UserDict.update(self, dict)
63
for key in dict.keys():
64
if key not in self._keys: self._keys.append(key)
67
return map(self.get, self._keys)
71
for key, value in self.items():
72
lines.append("%s: %s" % (key, value))
73
return '\n'.join(lines)
76
def convert_list(choices):
77
"""Convert a list of choices to an Odict (ordered dictionary).
78
choices may be in one of several formats:
80
string: 'one|two|three'
81
list: ['one', 'two', 'three']
82
dict: {'a': "Choice A", 'b': "Choice B"}
83
list-of-lists: [['a', "Choice A"], ['b', "Choice B"], ..]
85
Note: the dict form does not preserve order. Use list-of-lists
86
to maintain the specified order.
88
if type(choices) not in [str, list, dict]:
89
raise TypeError("choices must be a string, list, or dictionary.")
91
if type(choices) == str:
92
choices = choices.split('|')
93
return Odict(choices, choices)
95
if type(choices) == dict:
96
return Odict(choices.keys(), choices.values())
98
# choices is a list, but what kind?
101
if type(first) == str:
102
return Odict(choices, choices)
103
# list of 2-element string lists
104
elif type(first) == list and len(first) == 2:
105
choices, values = zip(*choices)
106
return Odict(choices, values)
108
raise TypeError("choices lists must either be"\
109
"['a', 'b', 'c'] or [['a', 'A'], ['b', 'B']] style.")