# Pre-PEP: Dictionary accumulator methods

Bengt Richter bokr at oz.net
Sat Mar 19 04:14:07 CET 2005

```On Sat, 19 Mar 2005 01:24:57 GMT, "Raymond Hettinger" <vze4rx4y at verizon.net> wrote:

>I would like to get everyone's thoughts on two new dictionary methods:
>
>        def count(self, value, qty=1):
>            try:
>                self[key] += qty
>            except KeyError:
>                self[key] = qty
>
>        def appendlist(self, key, *values):
>            try:
>                self[key].extend(values)
>            except KeyError:
>                self[key] = list(values)
>
>The rationale is to replace the awkward and slow existing idioms for dictionary
>based accumulation:
>
>    d[key] = d.get(key, 0) + qty
>    d.setdefault(key, []).extend(values)
>
>In simplest form, those two statements would now be coded more readably as:
>
>   d.count(key)
>   d.appendlist(key, value)
>
>In their multi-value forms, they would now be coded as:
>
>  d.count(key, qty)
>  d.appendlist(key, *values)

How about an efficient duck-typing value-incrementer to replace both? E.g. functionally like:

>>> class xdict(dict):
...         try: self[key] = self[key] + type(self[key])(incr)
...         except KeyError: self[key] = incr
...
>>> xd = xdict()
>>> xd
{}
>>> xd
{'x': 1}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in valadd
TypeError: int() argument must be a string or a number
>>> xd
{'y': [0, 1, 2], 'x': 1}
>>> xd
{'y': [0, 1, 2], 'x': 1, 'z': (1, 2)}
>>> xd['x']
101
>>> xd['y']
[0, 1, 2, 3, 4, 5]
>>> xd['z']
(1, 2, 3, 4)

>ISSUES
>------
>
>The proposed names could possibly be improved (perhaps tally() is more active
>and clear than count()).

I'm thinking the idea that the counting is happening with the value corresponding
to the key should be emphasised more. Hence valadd or such?

>
>The appendlist() method is not as versatile as setdefault() which can be used
>with other object types (perhaps for creating dictionaries of dictionaries).
>However, most uses I've seen are with lists.  For other uses, plain Python code
>suffices in terms of speed, clarity, and avoiding unnecessary instantiation of
>empty containers:
>
>    if key not in d:
>        d.key = {subkey:value}
>    else:
>        d[key][subkey] = value
>
Yes, but duck typing for any obj that supports "+" gets you a lot, ISTM at this stage
of this BF ;-)

Regards,
Bengt Richter

```