Pre-PEP: Dictionary accumulator methods

Bengt Richter bokr at oz.net
Fri Mar 18 22:14:07 EST 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):
 ...     def valadd(self, key, incr=1):
 ...         try: self[key] = self[key] + type(self[key])(incr)
 ...         except KeyError: self[key] = incr
 ...
 >>> xd = xdict()
 >>> xd
 {}
 >>> xd.valadd('x')
 >>> xd
 {'x': 1}
 >>> xd.valadd('x', range(3))
 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.valadd('y', range(3))
 >>> xd
 {'y': [0, 1, 2], 'x': 1}
 >>> xd.valadd('z', (1,2))
 >>> xd
 {'y': [0, 1, 2], 'x': 1, 'z': (1, 2)}
 >>> xd.valadd('x', 100)
 >>> xd['x']
 101
 >>> xd.valadd('y', range(3,6))
 >>> xd['y']
 [0, 1, 2, 3, 4, 5]
 >>> xd.valadd('z', (3,4))
 >>> 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



More information about the Python-list mailing list