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