Writing clean Python - setdefault
In Python, when you want to change a value in a dictionary, you must ensure that the key exists; otherwise, you'll encounter a KeyError
runtime error.
For example, suppose we want to create a new dictionary with lists as values. We check if the key exists: if it does, we append to the list; if it doesn't, we create a new list.
data = {"a": 1, "b": 4}
# verbose way
new_dict = {}
for (key, value) in data.items():
if key in new_dict:
new_dict[key].append(value)
else:
new_dict[key] = [value]
That’s rather ugly. We should only really use if else if we really need to, else its best to avoid.
A more Pythonic method is to use the setdefault
function:
new_dict = {}
for (key, value) in data.items():
value_from_key = new_dict.setdefault(key, [])
value_from_key.append(value)
Set default removes the need to check if the key is present. it will automatically set the value of the key to the second parameter if the key doesn’t exists. It also returns the value assigned to the key, in this case the array and so we append the value to it.
setdefault
eliminates the need to check if the key is present. If the key doesn't exist, it sets its value to the second argument provided. Additionally, setdefault
returns the current value for the key, so we can append directly to it.
In fact, we can make this even cleaner by using method chaining and eliminating the intermediate variable:
new = {}
for (key, value) in data.items():
new.setdefault(key, []).append(value)
Thats some pretty tasty looking python if you ask me.
Note: It's generally better practice to use the DefaultDict
class when you're creating the initial dictionary. However, when you don't have that luxury, setdefault
can be very useful.