On Fri, 2007-07-20 at 19:08 +0000, Alex Popescu wrote: > Hi all! > > I am pretty sure this has been asked a couple of times, but I don't seem > to find it on the archives (Google seems to have a couple of problems > lately). > > I am wondering what is the most pythonic way of dealing with missing > keys and default values. > > According to my readings one can take the following approaches: > > 1/ check before (this has a specific name and acronym that I haven't > learnt yet by heart) > > if not my_dict.has_key(key): > my_obj = myobject() > my_dict[key] = my_obj > else: > my_obj = my_dict[key]
This is called "Look before you leap." Note that "if key in my_dict" is preferred over has_key(). > 2/ try and react on error (this has also a specific name, but...) > > try: > my_obj = my_dict[key] > except AttributeError: > my_obj = myobject() > my_dict[key] = my_obj > This is called "It's easier to ask for forgiveness than permission." > 3/ dict.get usage: > > my_obj = my_dict.get(key, myobject()) > > I am wondering which one is the most recommended way? get usage seems > the clearest, but the only problem I see is that I think myobject() is > evaluated at call time, and so if the initialization is expensive you > will probably see surprises. All ways are equally acceptable. The main difference is in the amount of optimism the code conveys about the existence of the key. Number 1 and 3 convey the notion that you expect the key to be missing, that it's normal for the key to be missing. Number 2 conveys the notion that the key is only missing under exceptional circumstances. As you noted, number 3 is not good if it's expensive to initialize a myobject() instance, because the object will be created regardless of whether it'll be needed. In that case, you should go with number 1, or the following variant of number 3: my_obj = my_dict.get(key, None) if my_obj is None: my_obj = myobject() This only works if the dictionary doesn't contain Nones already. If it does, you would create a cheap sentinel object instead: sentinel = object() my_obj = my_dict.get(key, sentinel) if my_obj is sentinel: my_obj = myobject() HTH, -- Carsten Haese http://informixdb.sourceforge.net -- http://mail.python.org/mailman/listinfo/python-list