06. Python Dictionaries
๐ Unlock the power of Python Dictionaries! This guide dives deep into dictionary manipulation, methods, comprehensions, and best practices, equipping you with the skills to efficiently manage and utilize key-value pairs in your Python projects. ๐
What we will learn in this post?
- ๐ Introduction to Python Dictionaries
- ๐ Accessing and Modifying Dictionary Elements
- ๐ Dictionary Methods - Part 1
- ๐ Dictionary Methods - Part 2
- ๐ Dictionary Comprehensions
- ๐ Nested Dictionaries
- ๐ Dictionary Operations and Best Practices
- ๐ Conclusion!
Dictionaries: Key-Value Powerhouses ๐
Dictionaries in Python are like super-organized address books! They store information in key-value pairs. Think of it this way:
- The key is like the personโs name.
- The value is their address.
graph LR
A[Key] --> B(Value)
What Makes Dictionaries Special?
- Dictionaries are mutable, meaning you can change them after theyโre created.
- From Python 3.7 onwards, dictionaries remember the order in which you added items (insertion-ordered), and this is helpful when we have a need to remember the order.
- You create them using curly braces
{}.
1
2
3
# Creating a dictionary
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
print(my_dict) # Output: {'name': 'Alice', 'age': 30, 'city': 'New York'}
Dictionary Use Cases ๐ก
Dictionaries are useful for:
- Storing configuration settings.
- Representing objects with named properties.
- Counting frequencies of items, for example, how many times we encounter a word.
Resources: Python Dictionaries Documentation
Dictionary Fun: Accessing, Modifying, & More! ๐
Letโs explore how to work with dictionaries in Python! Theyโre like real-world dictionaries, pairing keys with values. ๐๏ธ
Accessing Values with Keys ๐
You grab a value by using its key inside square brackets: my_dictionary['key']. If the key doesnโt exist, youโll get a KeyError. Use the .get() method to avoid this! It returns None (or a default value you specify) if the key is missing.
1
2
3
4
my_dict = {'name': 'Alice', 'age': 30}
print(my_dict['name']) # Output: Alice
print(my_dict.get('city')) # Output: None
print(my_dict.get('city', 'Unknown')) # Output: Unknown
Modifying and Adding โ๏ธโ
Change a value by assigning a new one to its key: my_dictionary['key'] = new_value. To add a completely new key-value pair, simply assign a value to a new key: my_dictionary['new_key'] = value.
1
2
3
my_dict['age'] = 31 # Modifying
my_dict['city'] = 'New York' # Adding
print(my_dict) # Output: {'name': 'Alice', 'age': 31, 'city': 'New York'}
Deleting Items ๐๏ธ
Use the del keyword followed by the dictionary and the key in square brackets: del my_dictionary['key'].
1
2
del my_dict['age']
print(my_dict) # Output: {'name': 'Alice', 'city': 'New York'}
graph LR
D_START["Dictionary"]:::javaStyle --> D_ACCESS["Access Value"]:::jdbcStyle
D_START --> D_ADD["Add Key-Value"]:::driverStyle
D_START --> D_DEL["Delete Key"]:::dbStyle
D_ACCESS --> D_RESULT["Get Value"]:::useStyle
D_ADD --> D_RESULT
D_DEL --> D_RESULT
classDef javaStyle fill:#ff4f81,stroke:#c43e3e,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef jdbcStyle fill:#6b5bff,stroke:#4a3f6b,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef driverStyle fill:#ffd700,stroke:#d99120,color:#222,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef dbStyle fill:#00bfae,stroke:#005f99,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef useStyle fill:#ff9800,stroke:#f57c00,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
class D_START javaStyle;
class D_ACCESS jdbcStyle;
class D_ADD driverStyle;
class D_DEL dbStyle;
class D_RESULT useStyle;
linkStyle default stroke:#e67e22,stroke-width:3px;
For more in-depth learning check out these resources!
Dictionary Methods: Your Dictionary Toolkit! ๐งฐ
Dictionaries in Python are like treasure chests ๐ฐ, holding key-value pairs. Letโs explore some useful tools to manage them!
Accessing Dictionary Data
keys(): Unlocking the Keys
The .keys() method gives you a view object containing all the keys in your dictionary.
1
2
3
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
keys = my_dict.keys()
print(keys) # Output: frozenset(['name', 'age', 'city'])
Dictionary Comprehensions: Compact & Powerful! ๐
1
2
3
4
5
6
7
8
### <span style="color:#8e44ad">`values()`: Revealing the Values</span>
Similar to `.keys()`, `.values()` provides a _view object_ containing all the values.
```python
values = my_dict.values()
print(values) # Output: dict_values(['Alice', 30, 'New York'])
items(): Getting Key-Value Pairs
.items() returns a view object with key-value pairs as tuples. Super handy for looping!
1
2
3
4
5
6
7
8
9
items = my_dict.items()
print(items) # Output: dict_items([('name', 'Alice'), ('age', 30), ('city', 'New York')])
for key, value in my_dict.items():
print(f"Key: {key}, Value: {value}")
# Output:
# Key: name, Value: Alice
# Key: age, Value: 30
# Key: city, Value: New York
get(): Safe Retrieval
.get(key, default) retrieves the value for a given key. If the key doesnโt exist, it returns the default value (or None if no default is provided), avoiding errors.
1
2
3
4
5
age = my_dict.get("age")
print(age) # Output: 30
occupation = my_dict.get("occupation", "Unknown")
print(occupation) # Output: Unknown
Modifying Dictionaries
setdefault(): Adding if Absent
.setdefault(key, default) returns the value of the key, but also inserts the key with the given default value if the key is not already in the dictionary.
1
2
3
4
my_dict.setdefault("country", "USA")
print(my_dict) # Output: {'name': 'Alice', 'age': 30, 'city': 'New York', 'country': 'USA'}
#If 'country' already existed, the value would NOT be changed.
update(): Merging Dictionaries
.update(other_dict) merges another dictionary into the current one. If there are shared keys, the values from other_dict overwrite the existing ones.
1
2
3
new_data = {"age": 31, "occupation": "Engineer"}
my_dict.update(new_data)
print(my_dict) # Output: {'name': 'Alice', 'age': 31, 'city': 'New York', 'country': 'USA', 'occupation': 'Engineer'}
Resources:
Dictionary Methods Explained ๐
Letโs explore some handy dictionary methods in Python. Dictionaries are super useful for storing data in key-value pairs!
Removing Items ๐๏ธ
pop()
- Removes a specific key-value pair. You need to provide the key. If the key isnโt found, it raises an error (unless you provide a default value).
1
2
3
4
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
popped_value = my_dict.pop("age")
print(my_dict) # {'name': 'Alice', 'city': 'New York'}
print(popped_value) # 30
popitem()
- Removes and returns the last inserted key-value pair. Useful when you donโt care which item gets removed. Before Python 3.7, it removed an arbitrary item.
1
2
3
4
my_dict = {"name": "Alice", "age": 30, "city": "New York"}
removed_item = my_dict.popitem()
print(my_dict) # {'name': 'Alice', 'age': 30} (Order may vary before Python 3.7)
print(removed_item) # ('city', 'New York')
Clearing and Copying ๐งน
clear()
- Removes all items from the dictionary, leaving it empty.
1
2
3
my_dict = {"name": "Alice", "age": 30}
my_dict.clear()
print(my_dict) # {}
copy()
- Creates a shallow copy of the dictionary. Changes to the copy wonโt affect the original, and vice-versa (for simple data types).
1
2
3
4
5
my_dict = {"name": "Alice", "age": 30}
new_dict = my_dict.copy()
new_dict["age"] = 31
print(my_dict) # {'name': 'Alice', 'age': 30}
print(new_dict) # {'name': 'Alice', 'age': 31}
Creating from Keys ๐
fromkeys()
- Creates a new dictionary with keys from a sequence and a common value (default is
None).
1
2
3
keys = ["name", "age", "city"]
new_dict = dict.fromkeys(keys, "Unknown")
print(new_dict) # {'name': 'Unknown', 'age': 'Unknown', 'city': 'Unknown'}
Here is a resource link to get more info on Python Dictionaries: Python Dictionary Tutorial
Dictionary Comprehensions: ๐ ๏ธ A Quick Guide
Tired of writing long loops to make dictionaries? Dictionary comprehensions are here to help! They offer a super concise way to create dictionaries in just one line of code. Think of it as a short and sweet shortcut.
The Basics: Unpacking the Syntax
The magic formula is: {key: value for item in iterable}. Letโs break it down:
key: value: This defines what each key-value pair in your dictionary will look like.for item in iterable: This part is familiar! Itโs just like aforloop, looping through eachitemin youriterable(like a list or tuple).
Examples: Putting it into Practice
Simple Transformation
Letโs say you have a list of numbers and want to create a dictionary where the number is the key and its square is the value:
1
2
3
4
numbers = [1, 2, 3, 4, 5]
squares = {num: num**2 for num in numbers}
print(squares)
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Adding Filters: Keeping it Selective
Want to include only even numbers? Add an if condition!
1
2
3
4
numbers = [1, 2, 3, 4, 5, 6]
even_squares = {num: num**2 for num in numbers if num % 2 == 0}
print(even_squares)
# Output: {2: 4, 4: 16, 6: 36}
- The
if num % 2 == 0part ensures that only even numbers are processed.
Dictionary comprehensions can significantly reduce code and improve readability. They are a handy tool for any Python programmer.
Nested Dictionaries: Dictionaries within Dictionaries ๐
Nested dictionaries are simply dictionaries that contain other dictionaries as values. Think of it as a dictionary where some entries point to other, smaller dictionaries. They are used to represent complex, hierarchical data.
graph LR
ROOT["my_dict"]:::javaStyle --> PERSON["person"]:::jdbcStyle
PERSON --> NAME["name: Alice"]:::driverStyle
PERSON --> AGE["age: 30"]:::dbStyle
PERSON --> ADDRESS["address"]:::useStyle
ADDRESS --> STREET["street: 123 Main St"]:::jdbcStyle
ADDRESS --> CITY["city: Anytown"]:::dbStyle
classDef javaStyle fill:#ff4f81,stroke:#c43e3e,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef jdbcStyle fill:#6b5bff,stroke:#4a3f6b,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef driverStyle fill:#ffd700,stroke:#d99120,color:#222,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef dbStyle fill:#00bfae,stroke:#005f99,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
classDef useStyle fill:#ff9800,stroke:#f57c00,color:#fff,font-size:16px,stroke-width:3px,rx:14,shadow:6px;
class ROOT javaStyle;
class PERSON jdbcStyle;
class NAME driverStyle;
class AGE dbStyle;
class ADDRESS useStyle;
class STREET jdbcStyle;
class CITY dbStyle;
linkStyle default stroke:#e67e22,stroke-width:3px;
Accessing Nested Values ๐
You access nested values by chaining keys, like dictionary['key1']['key2']['key3']. Each key accesses a level deeper into the structure.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
my_dict = {
'person': {
'name': 'Alice',
'age': 30,
'address': {
'street': '123 Main St',
'city': 'Anytown'
}
}
}
# Accessing Alice's age:
age = my_dict['person']['age'] # 30
# Accessing Alice's street:
street = my_dict['person']['address']['street'] # '123 Main St'
print(age)
print(street)
# 30
# 123 Main St
Practical Use Cases ๐ผ
JSON-like Data Structures: Nested dictionaries are perfect for representing data similar to JSON format. This is super useful for working with APIs and configuration files.
Representing Complex Objects: Like a customer object containing address and order history dictionaries.
Configuration Management: Storing application settings organized by category.
1
2
3
4
5
6
7
8
9
10
11
# Example of JSON-like data
data = {
"widget": {
"debug": "on",
"window": {
"name": "main_window",
"width": 640,
"height": 480
}
}
}
| Feature | Dictionary (dict) | List (list) | Tuple (tuple) |
|---|---|---|---|
| Structure | Key-value pairs | Ordered items | Ordered items |
| Mutability | Mutable | Mutable | Immutable |
| Access | By key | By index | By index |
| Syntax | {} | [] | () |
| Typical Use | Mapping, fast lookup | Sequence, iteration | Fixed sequence, safety |
| Keys/Indices | Keys must be immutable | Indices (0, 1, โฆ) | Indices (0, 1, โฆ) |
1
2
3
4
5
6
7
8
9
10
11
12
13
# <span style="color:#e67e22">Dictionary Fun ๐: Operations and Tips</span>
Let's explore some handy dictionary tricks and how to use them wisely! Dictionaries are like real-world dictionaries: they hold _key-value_ pairs.
## <span style="color:#2980b9">Essential Dictionary Actions ๐ ๏ธ</span>
- **Membership Testing ( `in` )**: Quick check to see if a key exists. Super fast! ๐จ
```python
my_dict = {'apple': 1, 'banana': 2}
print('apple' in my_dict) # Output: True
print('orange' in my_dict) # Output: False
Iteration: Looping through the dictionary. You can loop through keys, values, or both! ๐
1 2 3 4 5 6 7
my_dict = {'apple': 1, 'banana': 2} for key in my_dict: # Loop through keys print(key) for value in my_dict.values(): # Loop through values print(value) for key, value in my_dict.items(): # Loop through keys and values print(f"{key}: {value}")
Merging Dictionaries (
|): Combines two dictionaries (Python 3.9+). Think of it as a friendly handshake!๐ค1 2 3 4
dict1 = {'a': 1, 'b': 2} dict2 = {'c': 3, 'd': 4} merged_dict = dict1 | dict2 print(merged_dict) # Output: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
Performance Notes and Best Practices ๐
- Speed Matters: Dictionary lookups (using keys) are generally very fast โ close to constant time! This is a big advantage.
- Choose Keys Wisely: Use immutable (unchangeable) data types like strings, numbers, or tuples as keys. Avoid using lists!
- Memory Management: Dictionaries can take up a fair bit of memory. Be mindful when working with very large datasets.
- Avoid Modification during Iteration: Modifying a dictionary while looping through it can lead to unexpected behavior. Create a copy or use a list to store the elements to be deleted/modified.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#Don't do this
my_dict = {'apple': 1, 'banana': 2, 'cherry':3}
for key in my_dict:
if my_dict[key] < 3:
del my_dict[key] #This is bad
#Instead you could do this:
my_dict = {'apple': 1, 'banana': 2, 'cherry':3}
keys_to_delete = []
for key in my_dict:
if my_dict[key] < 3:
keys_to_delete.append(key)
for key in keys_to_delete:
del my_dict[key]
print(my_dict) #Output {'cherry': 3}
๐ฏ Practice Project Assignment
๐ก Project: Contact Management System (Click to expand)
Your Challenge:
Build a simple contact management system using nested dictionaries that stores contact information and provides search and filter capabilities.
Implementation Hints:
- Use a main dictionary with contact IDs as keys and nested dictionaries as values containing name, phone, email, and tags
- Implement a search function that finds contacts by name using dictionary comprehension
- Create a filter function to get contacts by tag (e.g., 'work', 'family', 'friends')
- Use the
update()method to merge new contact information - Bonus: Add a function to export contacts to a formatted string showing all details, and calculate statistics like total contacts per tag using dictionary methods
Example Output:
Contact System: =============== Total contacts: 4 Contact C001: Name: Alice Johnson Phone: 555-0101 Email: alice@example.com Tags: ['work', 'friend'] Searching for 'Bob': Found: Bob Smith (C002) Filtering by tag 'work': 2 contacts found: Alice Johnson, Charlie Brown Statistics: work: 2 contacts family: 1 contact friend: 3 contacts
Share Your Solution! ๐ฌ
Got your contact manager working? Share your code in the comments! Feel free to add extra features like sorting contacts, validating email formats, or creating groups. Happy coding! ๐
Conclusion
Hope you enjoyed the read! ๐ฅณ Now itโs your turn! What are your takeaways? Any tips youโd like to share? Drop a comment below โ Iโm all ears! ๐โ๏ธ