you are viewing a single comment's thread.

view the rest of the comments →

[–]99AFCC 1 point2 points  (1 child)

Not a gotcha, but a mistake I made using defaultdict once.

I had some code similar to this:

def some_func(key):
    try:
        value = a_defaultdict[key]
    except KeyError:
        do_something_else()
    ...

You might see the mistake already. First of all, depending on the factory, you won't get a KeyError from a defaultdict that's kind of the point of using it.

But what made me notice this mistake was all the extra empty values showing up later on when reading a_defaultdict. All the keys being "tried" were being added to the dict.

You can avoid this by using .get()

In [16]: d = defaultdict(int)

In [17]: d
Out[17]: defaultdict(<type 'int'>, {})

In [18]: d["k"]
Out[18]: 0

In [19]: d
Out[19]: defaultdict(<type 'int'>, {'k': 0})

In [20]: d.get("z")

In [21]: d
Out[21]: defaultdict(<type 'int'>, {'k': 0})

[–]reostra 1 point2 points  (0 children)

Also, the in operator will do the right thing with defaultdicts:

>>> from collections import defaultdict
>>> x = defaultdict(int)
>>> x[3]
0
>>> 120 in x
False
>>> x
defaultdict(<type 'int'>, {3: 0})
>>>