Paul Hankin wrote: > On Sep 25, 12:51 pm, Mark Summerfield <[EMAIL PROTECTED]> > wrote: >> On 25 Sep, 12:19, Paul Hankin <[EMAIL PROTECTED]> wrote: >> >> >> >>> Recall sorted... >>> sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted >>> list >>> So why not construct sorteddicts using the same idea of sortedness? >>> sorteddict((mapping | sequence | nothing), cmp=None, key=None, >>> reverse=None) >>> Then we can specify the exact behaviour of sorteddicts: it's the same >>> as a regular dict, except when the order of keys is important they're >>> ordered as if they were sorted by sorted(keys, cmp=sd._cmp, >>> key=sd._key, reverse=sd._reverse). Here I imagine cmp, key and reverse >>> are stored in the new sorteddict as attributes _cmp, _key, _reverse - >>> obviously the actual implementation may differ. >>> This has the benefit of making sorteddict's behaviour explicit and >>> easy to understand, and doesn't introduce a new sorting API when we >>> already have a perfectly decent one. >>> The only problem here is the **kwargs form of the dict constructor >>> doesn't translate as we're using keyword args to pass in the sort >>> criterion. Perhaps someone has an idea of how this can be solved. If >>> nothing else, this constructor could be dropped for sorteddicts, and >>> sorteddict(dict(**kwargs), cmp=..., key=..., reverse=...) when that >>> behaviour is wanted. >>> I don't like the integral indexing idea or the slicing: indexing and >>> slicing are already part of python and it's bad to have different >>> syntax for the same concept on sorteddicts. I'd say it's not an >>> important enough for sorteddicts anyway. >>> -- >>> Paul Hankin >> This makes a lot of sense to me. But how do you envisage it would be >> implemented? > > Here's a first go. Sorting occurs when the keys are iterated over, > making it fast (almost as a dict) for construction, insertion, and > deletion, but slow if you're iterating a lot. You should look at some > use cases to decide if this approach is best, or if a sorted > datastructure should be used instead, but my instinct is that this is > a decent approach. Certainly, you're unlikely to get a simpler > implementation :) > > class sorteddict(dict): > "A sorted dictionary" > def __init__(self, arg=None, cmp=None, key=None, reverse=False): > if arg: > super(sorteddict, self).__init__(arg) > else: > super(sorteddict, self).__init__() > self._cmp = cmp > self._key = key > self._reverse = reverse > def keys(self): > return sorted(super(sorteddict, self).keys(), cmp=self._cmp, > key=self._key, reverse=self._reverse) > def iter_keys(self): > return (s for s in self.keys()) > def items(self): > return [(key, self[key]) for key in self.keys()] > def iter_items(self): > return ((key, self[key]) for key in self.keys()) > def values(self): > return [self[key] for key in self.keys()] > def iter_values(self): > return (self[key] for key in self.keys()) > def __str__(self): > return '{' + ', '.join('%s: %s' % (repr(k), repr(v)) > for k, v in self.iter_items()) + '}' > def __repr__(self): > return str(self) > def __iter__(self): > return self.iter_keys()
With this is the implementation, I'm definitely -1. Not because it's a bad implementation, but because if the iteration is always doing a sort, then there's no reason for a separate data structure. Just use sorted() directly on a regular dict. That has the advantage of being much more obvious about where the expensive operations are:: for key in sorted(d, ...): ... whatever you want to do ... IMHO, the only reason to introduce a sorteddict() is if it minimizes the cost of sorting the keys. STeVe -- http://mail.python.org/mailman/listinfo/python-list