Steven D'Aprano wrote: > class SortedDict(dict): > def __iter__(self): > for key in sorted(self.keys()): > yield key > > Note that using sorted(self) does not work.
That's because sorted() invokes __iter__() if present. To prevent the recursion you can explicitly invoke dict.__iter__(): >>> class SortedDict(dict): ... def __iter__(self): ... return iter(sorted(super(SortedDict, self).__iter__())) ... >>> sd = SortedDict(a=1, b=2, c=3) >>> list(sd) ['a', 'b', 'c'] Note that a list of keys is still built before the first key is yielded, and, unlike dict, you can modify your SortedDict while iterating over it: >>> for k in sd: ... if k == "b": sd["x"] = 42 ... >>> sd {'a': 1, 'x': 42, 'c': 3, 'b': 2} whereas: >>> d = dict(a=1, b=2, c=3) >>> for k in d: ... if k == "b": d["x"] = 42 ... Traceback (most recent call last): File "<stdin>", line 1, in <module> RuntimeError: dictionary changed size during iteration By the way, I think it would be worthwile to change super() to allow e. g. super(SomeClass, self)[...] as an alternate spelling for super(SomeClass, self).__getitem__(...) etc. With such an enhancement SortedDict would become class SortedDict(dict): def __iter__(self): # doesn't work in current Python iter(sorted(super(SortedDict, self))) Peter -- http://mail.python.org/mailman/listinfo/python-list