The addition of collections.defaultdict
in Python 2.5 greatly reduced the need for dict
's setdefault
method. This question is for our collective education:
- What is
setdefault
still useful for, today in Python 2.6/2.7? - What popular use cases of
setdefault
were superseded withcollections.defaultdict
?
defaultdict
is great when the default value is static, like a new list, but not so much if it's dynamic.For example, I need a dictionary to map strings to unique ints.
defaultdict(int)
will always use 0 for the default value. Likewise,defaultdict(intGen())
always produces 1.Instead, I used a regular dict:
Note that
dict.get(key, nextID())
is insufficient because I need to be able to refer to these values later as well.intGen
is a tiny class I build that automatically increments an int and returns its value:If someone has a way to do this with
defaultdict
I'd love to see it.I use
setdefault()
when I want a default value in anOrderedDict
. There isn't a standard Python collection that does both, but there are ways to implement such a collection.The different use case for
setdefault()
is when you don't want to overwrite the value of an already set key.defaultdict
overwrites, whilesetdefault()
does not. For nested dictionaries it is more often the case that you want to set a default only if the key is not set yet, because you don't want to remove the present sub dictionary. This is when you usesetdefault()
.Example with
defaultdict
:setdefault
doesn't overwrite:Here are some examples of setdefault to show its usefulness:
You could say
defaultdict
is useful for settings defaults before filling the dict andsetdefault
is useful for setting defaults while or after filling the dict.Probably the most common use case: Grouping items (in unsorted data, else use
itertools.groupby
)Sometimes you want to make sure that specific keys exist after creating a dict.
defaultdict
doesn't work in this case, because it only creates keys on explicit access. Think you use something HTTP-ish with many headers -- some are optional, but you want defaults for them:I commonly use
setdefault
for keyword argument dicts, such as in this function:It's great for tweaking arguments in wrappers around functions that take keyword arguments.