[Tutor] Keeping Dictonary Entries Ordered
spir
denis.spir at free.fr
Fri Feb 13 11:16:34 CET 2009
Le Fri, 13 Feb 2009 15:41:01 +1300,
John Fouhy <john at fouhy.net> a écrit :
> 2009/2/13 Eric Dorsey <dorseye at gmail.com>:
> > Alan, can you give a short snippet of what that would look like? I was
> > trying to code out some idea of how you'd retain insertion order using
> > another dict or a list and didn't get anywhere.
>
> Here's something basic:
>
> class o_dict(dict):
> def __init__(self, *args, **kw):
> dict.__init__(self, *args, **kw)
> self.__keylist = []
>
> def __setitem__(self, key, val):
> dict.__setitem__(self, key, val)
> if key not in self.__keylist:
> self.__keylist.append(key)
>
> def __iter__(self):
> return iter(self.__keylist)
>
> It will do the right thing if you do 'for key in odict:', but not for
> things like iteritems(). It will break if you delete keys from the
> dictionary, and the 'key not in self.__keylist' test will get slow if
> you have lots and lots of keys. It will also not do what you want if
> you initialise it as something like: o_dict(foo=1, bar=2)
An issue is that obviously you can't initialize an ordered dict from another dict or a set of keyword arguments, for those are unordered. So I simply took **kwargs off the __init__ method. And let as single possible init stuff a list of (key,value) pairs. Also, as a built_in dict accepts only a single arg, there is no need for *arg: the seq of pairs must be contained in a list or tuple. From the pairs can then the keylist be properly initialised. This led me to something similar to the following:
class Ordict(dict):
def __init__(self, pairs):
dict.__init__(self, pairs)
self._keylist = [k for (k,v) in pairs]
def __setitem__(self, key, val):
dict.__setitem__(self, key, val)
if key not in self._keylist:
self._keylist.append(key)
def __iter__(self):
return iter(self._keylist)
def __str__(self):
pair_texts = ["%s:%s" % (k,self[k]) for k in self._keylist]
return "[%s]" % ", ".join(pair_texts)
od = Ordict([('a',1), ('d',4), ('b',2)])
od[' '] = 0 ; od['c'] = 3
print od._keylist
for k in od: print "%s: %s " % (k,od[k]),
print; print od
==>
['a', 'd', 'b', ' ', 'c']
a: 1 d: 4 b: 2 : 0 c: 3
[a:1, d:4, b:2, :0, c:3]
I remember there were some more minor issues.
Denis
------
la vida e estranya
More information about the Tutor
mailing list