- Creating a dictionary
- Read a value of a key
- Add an element
- Update an element
- Add/Update multiple elements
- Delete an element
- Get a key-value pair and delete it at once
- Get the last value and delete it
- Check if a key exists in a dictionary
- Get the first key, value, key-value pair
- Create a key-value automatically if it doesn’t exist
- Sort a dict
- Dict to string/json
Creating a dictionary
There are two ways to create a dictionary.
empty_dict1 = {}
empty_dict2 = dict()
# empty_dict1: True, {}
print(f"empty_dict1: {isinstance(empty_dict1, dict)}, {empty_dict1}")
# empty_dict2: True, {}
print(f"empty_dict2: {isinstance(empty_dict2, dict)}, {empty_dict2}")
Just using {}
or dict()
class explicitly.
data_dict = {1: "Apple", 2: "Orange", 3: "Strawberry"}
data_dict2 = dict(one="Apple", two="Orange")
# {1: 'Apple', 2: 'Orange', 3: 'Strawberry'}
print(data_dict)
# {'one': 'Apple', 'two': 'Orange'}
print(data_dict2)
If you want to use number as a key, you can’t use dict()
constructor because it accepts only string.
print({1.1: 1}) # OK
print(dict(1=1)) # NG
print(dict(1.1=1)) # NG
Read a value of a key
A value can be read by specifying the key in the square brackets.
# 1: Apple, 2: Orange, 3: Strawberry
print(f"1: {data_dict[1]}, 2: {data_dict[2]}, 3: {data_dict[3]}")
# one: Apple, two: Orange
print(f"one: {data_dict2['one']}, two: {data_dict2['two']}")
Note that double quotes can’t be used for string key. It must be single quotes.
data_dict2["one"] # NG
It’s also possible to use get
method instead.
# 1: Apple
print(f"1: {data_dict.get(1)}")
Difference between get method and brackets
Let’s check the difference. Reading a value with brackets can raise an KeyError
.
try:
print(data_dict[999])
except KeyError as err:
# KeyError: 999
print(f"KeyError: {err}")
# 1: None
print(f"1: {data_dict.get(999)}")
# 1: default-value 999
print(f"1: {data_dict.get(999, 'default-value 999')}")
But get()
method doesn’t raise an error. If the key doesn’t exist, it returns None
by default. If you need your own default value, just specify it to the second parameter.
Add an element
Adding an element is simple.
data_dict[4] = "Blueberry"
print(data_dict)
# {1: 'Apple', 2: 'Orange', 3: 'Strawberry', 4: 'Blueberry'}
Update an element
Update an element is the same as adding an element. If the key exists, the value is updated. Otherwise, added.
data_dict[4] = "Rasberry"
print(data_dict)
Add/Update multiple elements
Use update
method if multiple elements need to be updated/added at once.
# {1: 'Apple', 2: 'Orange', 3: 'Strawberry', 4: 'Rasberry'}
print(data_dict)
data_dict.update({1: "Green Apple", 4: "Riped Rasberry", 5: "Something", 6: "Empty"})
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 4: 'Riped Rasberry', 5: 'Something', 6: 'Empty'}
print(data_dict)
If the key is string, the key-value pairs can be added as follows.
# {'one': 'Apple', 'two': 'Orange'}
print(data_dict2)
data_dict2.update({"eight":"value 8"}, nine="value 9", ten="value 10")
# {'one': 'Apple', 'two': 'Orange', 'eight': 'value 8', 'nine': 'value 9', 'ten': 'value 10'}
print(data_dict2)
Delete an element
An element can be deleted with del
keyword but an error is raised if the key doesn’t exist.
try:
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 4: 'Riped Rasberry', 5: 'Something', 6: 'Empty'}
print(data_dict)
del data_dict[4]
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 5: 'Something', 6: 'Empty'}
print(data_dict)
del data_dict[4]
except KeyError as err:
print(f"KeyError occurred. Key: {err}")
Use clear()
method if it’s necessary to delete all the elements
copied_dict = data_dict.copy()
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 5: 'Something', 6: 'Empty'}
print(data_dict)
data_dict.clear()
# {}
print(data_dict)
Get a key-value pair and delete it at once
Use pop()
method if you need to remove the element after reading it.
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 5: 'Something', 6: 'Empty'}
print(data_dict)
pop_data = data_dict.pop(6)
# Empty
print(pop_data)
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 5: 'Something'}
print(data_dict)
If you want to try to get the key-value pair anyway without knowing if the key exists, specify the default value to the second parameter.
pop_data = data_dict.pop(99999, "DEFAULT-VALUE")
print(pop_data) # DEFAULT-VALUE
If it exists, the actual value is returned. Otherwise, default value.
Get the last value and delete it
If you don’t need to specify a key and just want to get a pair and delete it one by one, you can use popitem()
.
data_dict3 = dict(one="value1", two="value2", three="value3", four="value4")
# ('four', 'value4')
print(data_dict3.popitem())
# {'one': 'value1', 'two': 'value2', 'three': 'value3'}
print(data_dict3)
data_dict3.popitem()
data_dict3.popitem()
data_dict3.popitem()
# {}
print(data_dict3)
try:
data_dict3.popitem()
except Exception as err:
# 'popitem(): dictionary is empty'
print(err)
Check if a key exists in a dictionary
To check if a key is included in the dictionary, in
keyword can be used.
for key in [1, 3, 4]:
if key in copied_dict:
print(f"data_dict contains key {key}")
else:
print(f"data_dict doesn't contain key {key}")
# data_dict contains key 1
# data_dict contains key 3
# data_dict doesn't contain key 4
Get the first key, value, key-value pair
Dictionary has keys()
, values()
, and items()
but it can’t directly be read by using square brackets. It needs to be wrapped with list
first.
# {1: 'Green Apple', 2: 'Orange', 3: 'Strawberry', 5: 'Something', 6: 'Empty'}
print(copied_dict)
# 1
print(list(copied_dict.keys())[0])
# Green Apple
print(list(copied_dict.values())[0])
# (1, 'Green Apple')
print(list(copied_dict.items())[0])
Create a key-value automatically if it doesn’t exist
In some cases, we need to assign a default value if the key doesn’t exist in the dict. Let’s assume that we want to create a histogram. The key is int and the value is also int to indicate how many times the number appears.
We need to implement it in the following way.
count_dict: Dict[int, int] = {}
for num in range(10):
num = int(random.random() * 5)
if num not in count_dict:
print(f"new key was created [{num}]")
count_dict[num] = 0
count_dict[num] += 1
for key, value in count_dict.items():
print(f"key: {key}, value: {value}")
The main issue here is to assign a value to the key. In other words, we must create the key before incrementing the current value. The result looks as follows.
new key was created [3]
new key was created [1]
new key was created [0]
key: 3, value: 6
key: 1, value: 3
key: 0, value: 1
To make the code clearer, we can use defaultdict
that automatically creates the key with the default value. We don’t have to care whether the key exists or not. The following code doesn’t contain if condition and thus the code is more readable.
from collections import defaultdict
count_dict: Dict[int, int] = defaultdict(int)
for num in range(10):
num = int(random.random() * 5)
count_dict[num] += 1
for key, value in count_dict.items():
print(f"key: {key}, value: {value}")
# key: 0, value: 2
# key: 4, value: 6
# key: 3, value: 1
# key: 2, value: 1
defaultdict
accepts a callback to return the default value. If we want to assign an arbitrary value, we can pass a lambda there.
count_dict: Dict[int, int] = defaultdict(lambda : 5)
for num in range(10):
num = int(random.random() * 5)
count_dict[num] += 1
for key, value in count_dict.items():
print(f"key: {key}, value: {value}")
# key: 1, value: 9
# key: 3, value: 8
# key: 2, value: 6
# key: 0, value: 7
As you can see from the result, the sum of the values is bigger than 10. If you are not familiar with lambda, check the following post.
Sort a dict
If a dict needs to be sorted, sorted()
function must be used. Note that a dict can’t be passed directly but dict.items()
needs to be specified as a first parameter. key
property requires a callback for the sorting logic.
dict_data = {
"1": {"id": 2, "value": "value 2"},
"2": {"id": 5, "value": "value 5"},
"3": {"id": 1, "value": "value 1"},
"4": {"id": 3, "value": "value 3"},
}
sorted_dict = sorted(dict_data.items(), key=lambda pair: pair[1]["id"])
for entry in sorted_dict:
print(entry)
# ('3', {'id': 1, 'value': 'value 1'})
# ('1', {'id': 2, 'value': 'value 2'})
# ('4', {'id': 3, 'value': 'value 3'})
# ('2', {'id': 5, 'value': 'value 5'})
pair[0]
is a key and pair[1]
is a value.
Dict to string/json
The dict needs to be converted to str if it needs to be written to a log or file. How can we convert a dict to str?
Convert dict to str by str()
The easiest way is to use str
.
data = {
"pineapple": 10,
"apple juice": 4,
"orange": 6,
"water melon": 11
}
# <class 'str'>
print(type(str(data)))
# {'pineapple': 10, 'apple juice': 4, 'orange': 6, 'water melon': 11}
print(str(data))
All key-value pairs are printed as expected. It can convert to str without any error even if it contains a tuple in the key.
class_key = {
(1, 2, 3): 1,
(1): 2,
(4): 3,
5: 4,
}
# {(1, 2, 3): 1, 1: 2, 4: 3, 5: 4
print(str(class_key))
Convert dict to str by using json.dumps
The previous way is not nice when we want to write the dict key-value pairs to log file. It’s not readable. In this case, json.dumps()
is a good choice.
It converts a dict to str in the same way as str()
if only data is passed.
import json
# {"pineapple": 10, "apple juice": 4, "orange": 6, "water melon": 11}
print(json.dumps(data))
Let’s make it more readable. The output looks better with indent
. Furthermore, it sorts automatically with sort_keys=True
.
# {
# "apple juice": 4,
# "orange": 6,
# "pineapple": 10,
# "water melon": 11
# }
print(json.dumps(data, sort_keys=True, indent=2))
I guess this is a special case but we can change the separator too.
# {
# "apple juice" -> 4 |
# "orange" -> 6 |
# "pineapple" -> 10 |
# "water melon" -> 11
# }
print(json.dumps(data, sort_keys=True, indent=2, separators=(" |", " -> ")))
The colon is replaced with an arrow and the new line is replaced with a vertical line.
Note that json.dumps()
raises a type error if the dict contains non-basic types. skipkeys=True
ignores the error in this case.
class_key = {
(1, 2, 3): 1,
(1): 2,
(4): 3,
5: 4,
}
try:
print(json.dumps(class_key))
except TypeError as err:
# keys must be str, int, float, bool or None, not tuple
print(err)
# {"1": 2, "4": 3, "5": 4}
print(json.dumps(class_key, skipkeys=True))
Comments