Handy defaultdict's in Python You Must Know About!

Updated: Jun 11, 2018


Okay, here’s interesting scenario which you may have encountered before – lets say we have a dictionary which has string keys and list values. Now we will have a block of code which is supposed to check keys, if present append values to existing list and if not, create empty list and put value under it for the key. This is how it will look:


class Job:

def __init__(self, name):

self._name = name


class ConfigManager:

def __init__(self):

self._config = {}

def AddJob(self, category, job):

if category in self._config:

self._config[category].append( job )

else:

joblist = [ job ]

self._config[category] = joblist


configManager = ConfigManager()

configManager.AddJob("TaskPool", Job("FileReads"))

configManager.AddJob("TaskPool", Job("FileWrites"))

configManager.AddJob("CPUCrunchingJobPool", Job("SpreadsheetProcessing"))



Now this is fine, but if/else in AddJob could be avoided. If we did not do that we will get KeyError for disctionary. Python has a nice collection.defaultdict type which perfectly fits in our case. This is how we can rewrite AddJob function instead:


class Job:

def __init__(self, name):

self._name = name


class ConfigManager:

def __init__(self):

from collections import defaultdict

self._config = defaultdict(list)


def AddJob(self, category, job):

self._config[category].append( job )


configManager = ConfigManager()

configManager.AddJob("TaskPool", Job("FileReads"))

configManager.AddJob("TaskPool", Job("FileWrites"))

configManager.AddJob("CPUCrunchingJobPool", Job("SpreadsheetProcessing"))

print(configManager._config)


Result:

defaultdict(<class 'list'>, {'TaskPool': [<__main__.Job object at 0x03114710>, <__main__.Job object at 0x03114730>], 'CPUCrunchingJobPool': [<__main__.Job object at 0x03114770>]})


Did you notice our function came down to one liner. So what just happened here? Python’s defaultdict initializes key-value for us when key is not found in dictionary. This is good but watch for any side effects since this is equally risky, too, if not used correctly. Nevertheless, like in case of our AddJob interface, it comes handy numerous times!