Le Fri, 13 Feb 2009 15:41:01 +1300,
John Fouhy <[email protected]> a écrit :

> 2009/2/13 Eric Dorsey <[email protected]>:
> > 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
_______________________________________________
Tutor maillist  -  [email protected]
http://mail.python.org/mailman/listinfo/tutor

Reply via email to