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