Idiomatic dictionaries

get - default value of a non existing key while accessing

Especially handy if you're unsure about the presence of a key.

In [1]:
my_dict = {'a': 1, 'b': 2, 'c': 3}

Don't do it like this.

In [2]:
if 'g' in my_dict:
    value = my_dict['g']
else:
    value = 'some default value'
print(value)
some default value

Or like this.

In [3]:
try:
    value = my_dict['g']
except KeyError:
    value = 'some default value'
print(value)
some default value

Do it like this!

In [4]:
value = my_dict.get('g', 'some default value')
print(value)
some default value

Note that if you don't provide the default value for get, the return value will be None if the key is not present in the dictionary

In [5]:
value = my_dict.get('g')
print(value is None)
True

setdefault - same as get but also sets the value if not present

Don't do it like this.

In [6]:
my_dict = {'a': 1, 'b': 2, 'c': 3}

key = 'g'
if key in my_dict:
    value = my_dict[key]
else:
    value = 'some default value'
    my_dict[key] = value
    
print(value)
print(my_dict)
some default value
{'g': 'some default value', 'c': 3, 'b': 2, 'a': 1}

Let's do it like this!

In [7]:
my_dict = {'a': 1, 'b': 2, 'c': 3}

key = 'g'
value = my_dict.setdefault(key, 'some default value')

print(value)
print(my_dict)
some default value
{'g': 'some default value', 'c': 3, 'b': 2, 'a': 1}

Comprehensions

Let's say we have a collection of numbers and we want to store those as a dictionary where the number is key and it's square is the value.

In [8]:
numbers = (1, 5, 10)

Don't do it like this.

In [9]:
squares = {}
for num in numbers:
    squares[num] = num**2
print(squares)
{1: 1, 10: 100, 5: 25}

Do it like this!

In [10]:
squares = {num: num**2 for num in numbers}
print(squares)
{1: 1, 10: 100, 5: 25}

Another example

In [11]:
keys = ('a', 'b', 'c')
values = [True, 100, 'John Doe']

Don't do it like this.

In [12]:
my_dict = {}
for idx, key in enumerate(keys):
    my_dict[key] = values[idx]
print(my_dict)
{'c': 'John Doe', 'b': 100, 'a': True}

Do it like this!

In [13]:
my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict)

# Or even like this:
my_dict2 = dict(zip(keys, values))

assert my_dict2 == my_dict
{'c': 'John Doe', 'b': 100, 'a': True}

Looping

In [14]:
my_dict = {'age': 83, 'is gangster': True, 'name': 'John Doe'}

Don't do it like this.

In [15]:
for key in my_dict:
    val = my_dict[key]
    print('key: {:15s} value: {}'.format(key, val))
key: is gangster     value: True
key: age             value: 83
key: name            value: John Doe

Do it like this!

In [16]:
for key, val in my_dict.items():
    print('key: {:15s} value: {}'.format(key, val))
key: is gangster     value: True
key: age             value: 83
key: name            value: John Doe