Keeping track of things with dictionaries
Peter Otten
__peter__ at web.de
Sun Apr 6 04:23:38 EDT 2014
Giuliano Bertoletti wrote:
> I frequently use this pattern to keep track of incoming data (for
> example, to sum up sales of a specific brand):
>
> =====================================
>
> # read a brand record from a db
> ...
>
> # keep track of brands seen
> obj = brands_seen.get(brandname)
> if obj is None:
> obj = Brand()
> brands_seen[brandname] = obj
>
> obj.AddData(...) # this might for example keep track of sales
>
> =====================================
>
> as you might guess, brands_seen is a dictionary whose keys are
> brandnames and whose values are brand objects.
>
> Now the point is: is there a cleverer way to do this?
>
> Basically what I'm doing is query the dictionary twice if the object
> does not exist.
>
> What I would like to understand is if there's some language built-in
> logic to:
>
> - supply a function which is meant to return a new object
> - have the interpreter to locate the point in the dictionary where the
> key is to be
> - if the key is already there, it returns the value/object associated
> and stops
> - if the key is not there, it calls the supplied function, assigns the
> returned value to the dictionary and return the object.
Cudos, you give a precise discription of your problem in both english and
code.
There is a data structure in the stdlib that fits your task. With a
collections.defaultdict your code becomes
from collections import defaultdict
brands_seen = defaultdict(Brand)
brands_seen[brandname].add_data(...) # Method name adjusted to PEP 8
Side note: If you needed the key in the construction of the value you would
have to subclass
class BrandsSeen(dict):
def __missing__(self, brandname):
result = self[brandname] = Brand(brandname)
return result
brands_seen = BrandsSeen()
brands_seen[brandname].add_data(...)
More information about the Python-list
mailing list