[Python-ideas] OrderedCounter and OrderedDefaultDict

Wes Turner wes.turner at gmail.com
Fri Feb 12 17:20:06 EST 2016


This seems to keep a consistent __init__ signature with OrderedDict (by
.pop()-ing 'default_factory' from kwargs instead of specifying as a
positionalkwarg):

class OrderedDefaultDict(OrderedDict):

    def __init__(self, *a, **kw):
        default_factory = kw.pop('default_factory', self.__class__)
        OrderedDict.__init__(self, *a, **kw)
        self.default_factory = default_factory

    def __missing__(self, key):
        self[key] = value = self.default_factory()
        return value

I've added a few tests (as well as to_json, and _repr_json_
https://gist.github.com/westurner/be22dba8110be099a35e/c1a3a7394e401d4742df0617900bde6ab2643300#file-ordereddefaultdict-py-L120-L122

(Without this fix,
json.loads(output_json, object_pairs_hook=OrderedDefaultDict)
doesn't seem to work).


On Fri, Nov 13, 2015 at 11:17 PM, Andrew Barnert <abarnert at yahoo.com> wrote:

> On Nov 13, 2015, at 20:46, Wes Turner <wes.turner at gmail.com> wrote:
>
> On Fri, Oct 16, 2015 at 9:08 PM, Andrew Barnert via Python-ideas <
> python-ideas at python.org> wrote:
>
>> Actually, forget all that; it's even simpler.
>>
>> At least in recent 3.x, the only thing wrong with inheriting from both
>> types, assuming you put OrderedDict first, is the __init__ signature. So:
>>
>>     class OrderedDefaultDict(OrderedDict, defaultdict):
>>         def __init__(self, default_factory=None, *a, **kw):
>>             OrderedDict.__init__(self, *a, **kw)
>>             self.default_factory = default_factory
>>
>> More importantly, because __missing__ support is built into dict, despite
>> the confusing docs for defaultdict, you don't really need defaultdict at
>> all here:
>>
>>     class OrderedDefaultDict(OrderedDict):
>>         def __init__(self, default_factory=None, *a, **kw):
>>             OrderedDict.__init__(self, *a, **kw)
>>             self.default_factory = default_factory
>>         def __missing__(self, key):
>>             self[key] = value = default_factory()
>>             return value
>>
>> And either of these should work with 2.5+ (according to
>> https://docs.python.org/2/library/stdtypes.html#dict that's when
>> dict.__missing__ was added).
>>
>>
> Thanks!
>
> - [ ] Could/should maybe either of these make it into the standard library,
> that would save a fair amount of copying.
>
>
> You could say the same about everything in the recipes, every one-liner
> like "def identity(x): return x", and so on. But most such things aren't
> used that often, and there's a cost to putting them in the stdlib—more for
> people to learn and remember, more code to be maintained, bigger downloads,
> etc. So just saying "maybe it would save some copying" isn't an argument
> for adding it to the stdlib.
>
> Adding OrderedDefaultDict as a docs recipe (as OrderedCounter already is)
> might be worth doing.
> Reorganizing the docs a bit to make it more obvious (by better
> highlighting __missing__, and making it clear that it's a method of dict
> rather than something special about defaultdict) seems even more likely to
> be worth it. If someone has an idea of how it should read, just file a docs
> bug and submit a patch and see if whoever's in charge of that area says it
> needs to come back here.
>
> .. Great in combination w/ dict views:
> https://docs.python.org/2/library/stdtypes.html#dictionary-view-objects
>
>
> Of course, and that works out of the box.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160212/2e8adf96/attachment.html>


More information about the Python-ideas mailing list