Pre-PEP: Dictionary accumulator methods

Steven Bethard steven.bethard at gmail.com
Sun Mar 27 16:27:41 EST 2005


Michele Simionato wrote:
> FWIW, here is my take on the defaultdict approach:
> 
> def defaultdict(defaultfactory, dictclass=dict):
>     class defdict(dictclass):
>         def __getitem__(self, key):
>             try:
>                 return super(defdict, self).__getitem__(key)
>             except KeyError:
>                 return self.setdefault(key, defaultfactory())
>     return defdict
> 
> d = defaultdict(int)()
> d["x"] += 1
> d["x"] += 1
> d["y"] += 1
> print d
> 
> d = defaultdict(list)()
> d["x"].append(1)
> d["x"].append(2)
> d["y"].append(1)
> print d
> 
>               Michele Simionato

Very pretty! =)

It does mean, however, that if the defaultfactory function takes any 
arguments, you have to wrap the function to make this work.  I'd 
probably prefer something like:

py> def defaultdict(*args, **kwargs):
...     defaultfactory, args = args[0], args[1:]
...     class defdict(dict):
...         def __getitem__(self, key):
...             try:
...                 return super(defdict, self).__getitem__(key)
...             except KeyError:
...                 return self.setdefault(key, defaultfactory(
...                     *args, **kwargs))
...     return defdict
...
py> d = defaultdict(int)()
py> d['x'] += 1
py> d['x'] += 1
py> d['y'] += 1
py> d
{'y': 1, 'x': 2}
py> d = defaultdict(list, [0])()
py> d['x'].append(1)
py> d['x'].append(2)
py> d['y'].append(1)
py> d
{'y': [0, 1], 'x': [0, 1, 2]}

That said, I still think a dictools module is a better solution to this 
problem.

STeVe



More information about the Python-list mailing list