The Invent with Python Blog

Wed 05 June 2019

Pythonic Ways to Use Dictionaries

Posted by Al Sweigart in python   

Python dictionaries are a useful part of the language. In addition to having the ability to store keys and values, you can also use dictionary methods to manipulate those values, and you can use dictionaries to write more concise code.

Use get() and setdefault() with Dictionaries

Trying to access a dictionary key that doesn’t exist will result in a KeyError error, so programmers often will write unpythonic code to avoid the situation like this:

>>> # Unpythonic Example
>>> workDetails = {}
>>> if 'hours' in spam:
...     hoursWorked = workDetails['hours']
... else:
...     hoursWorked = 0 # Default to 0 if the 'hours' key doesn't exist.
...
>>> hoursWorked
0

This pattern happens so often that dictionaries have a get() method that allows you specify a default value to return when a key doesn’t exist in the dictionary. The following code is equivalent to the previous example, but is pythonic:

>>> # Pythonic Example
>>> workDetails = {}
>>> hoursWorked = spam.get('hours', 0)
>>> hoursWorked
0

If you find yourself writing if statements that check whether a key exists and provide a default value when the key is absent, use the get() method instead.

Conversely, you may want to set a default value if a key doesn’t exist. For example, if the dictionary in workDetails doesn’t have an 'hours' key, then the instruction workDetails['hours'] += 10 would result in a KeyError error. You may want to add code that checks for the key’s absence and sets a default value:

>>> # Unpythonic Example
>>> workDetails = {}
>>> if 'hoursWorked' not in workDetails:
...     workDetails['hours'] = 0
...
>>> workDetails['hours'] += 10
>>> workDetails['hours']
10

The previous example is unpythonic. Because this pattern is also common, dictionaries have a more pythonic setdefault() method. The following code is equivalent to the previous example:

>>> # Pythonic Example
>>> workDetails = {}
>>> workDetails.setdefault('hours', 0) # Does nothing if 'hours' exists.
0
>>> workDetails['hours'] += 10
>>> workDetails['hours']
10

If you find yourself writing if statements that check if a key exists in a dictionary and sets a default value if the key is absent, use the setdefault() method instead.

Python Uses Dictionaries Instead of a Switch Statement

Languages such as Java have a switch statement, which is a kind of if-elif-else statement that runs code based on the values of a single variable or expression. Python doesn’t have a switch statement, but a switch statement is similar to the following Python code, which sets the holiday variable based on the value of the month variable:

>>> # Unpythonic Example
if season == 'Winter':
    holiday = 'Christmas'
elif season == 'Spring':
    holiday = 'Easter'
elif season == 'Summer':
    holiday = 'American Independence Day'
elif season == 'Fall':
    holiday = 'Halloween'
else:
    holiday = 'Personal day off'

Handling code by using if statements to mimic switch statements is unpythonic. By default, Java switch statements have “fall-through” that requires each block end with a break statement. Otherwise, the execution continues on the next block. Forgetting to add this break statement is a common source of bugs. However, all the if-elif statements in our Python example are not much better since they can be overly verbose. Some Python programmers prefer to set up a dictionary value instead of using if-elif statements. The following concise and pythonic code is equivalent to the previous example:

>>> # Pythonic Example
holiday = {'Winter': 'Christmas',
           'Spring': 'Easter',
           'Summer': 'American Independence Day',
           'Fall':   'Halloween'}.get(season, 'Personal day off')

This code is just a single assignment statement. The value stored in holiday is the return value of the get() method call, which returns the value for the key that season is set to. If the season key doesn’t exist, then get() returns 'Personal day off'. Using a dictionary will result in more concise code, but it can also make your code harder to read. It’s up to you whether to use this convention or not.