7 min read
ā¢Question 6 of 41easyDictionaries in Python
Working with Python dictionaries.
What You'll Learn
- How dictionaries work internally (hash tables)
- All dictionary methods and operations
- Dictionary comprehensions
- Common patterns and best practices
- Performance characteristics
Understanding Python Dictionaries
Dictionaries are Python's built-in mapping type - unordered collections of key-value pairs. They use hash tables internally, providing O(1) average-case lookup, insertion, and deletion.
Dictionaries are defined by curly braces {} with key-value pairs separated by colons. They're essential for:
- Storing structured data
- Fast lookups by key
- Counting and grouping
- Caching and memoization
Creating Dictionaries
code.pyPython
# Empty dictionary
empty1 = {}
empty2 = dict()
# With initial values
person = {
"name": "John",
"age": 30,
"city": "NYC"
}
# Using dict() constructor
d1 = dict(name="Alice", age=25)
d2 = dict([("a", 1), ("b", 2)]) # From list of tuples
d3 = dict(zip(["a", "b"], [1, 2])) # From two lists
# From keys with default value
keys = ["a", "b", "c"]
d = dict.fromkeys(keys, 0) # {"a": 0, "b": 0, "c": 0}Key Requirements
Keys must be hashable (immutable):
code.pyPython
# Valid keys
d = {
"string": 1, # String
42: "number", # Integer
(1, 2): "tuple", # Tuple
True: "boolean", # Boolean
}
# Invalid keys (will raise TypeError)
# d = {[1, 2]: "list"} # Lists are mutable
# d = {{"a": 1}: "dict"} # Dicts are mutableAccessing Values
code.pyPython
person = {"name": "John", "age": 30}
# Direct access (raises KeyError if missing)
print(person["name"]) # "John"
# print(person["email"]) # KeyError!
# Using get() - safe access with default
print(person.get("name")) # "John"
print(person.get("email")) # None
print(person.get("email", "N/A")) # "N/A"
# Check if key exists
if "name" in person:
print(person["name"])
# setdefault - get or set default
person.setdefault("country", "USA") # Sets if missing, returns valueModifying Dictionaries
code.pyPython
person = {"name": "John"}
# Add or update single key
person["age"] = 30
person["age"] = 31 # Update
# Update multiple keys
person.update({"city": "NYC", "job": "Dev"})
person.update(country="USA") # Keyword args
# Python 3.9+ merge operators
d1 = {"a": 1}
d2 = {"b": 2}
merged = d1 | d2 # {"a": 1, "b": 2}
d1 |= d2 # In-place merge
# Remove keys
del person["age"] # Raises KeyError if missing
age = person.pop("age", None) # Safe remove with default
item = person.popitem() # Remove and return last item
person.clear() # Remove all itemsDictionary Methods
| Method | Description | Returns |
|---|---|---|
get(key, default) | Get value safely | value or default |
keys() | All keys | dict_keys view |
values() | All values | dict_values view |
items() | All key-value pairs | dict_items view |
pop(key, default) | Remove and return | value |
popitem() | Remove last item | (key, value) tuple |
update(dict) | Merge dictionaries | None |
setdefault(key, val) | Get or set default | value |
copy() | Shallow copy | dict |
clear() | Remove all items | None |
code.pyPython
person = {"name": "John", "age": 30, "city": "NYC"}
# Views are dynamic
keys = person.keys() # dict_keys(['name', 'age', 'city'])
values = person.values() # dict_values(['John', 30, 'NYC'])
items = person.items() # dict_items([...])
# Iterate
for key in person:
print(key)
for key, value in person.items():
print(f"{key}: {value}")Dictionary Comprehension
code.pyPython
# Basic syntax: {key_expr: value_expr for item in iterable}
squares = {x: x**2 for x in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# With condition
evens = {x: x**2 for x in range(10) if x % 2 == 0}
# {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# Swap keys and values
original = {"a": 1, "b": 2}
swapped = {v: k for k, v in original.items()}
# {1: "a", 2: "b"}
# From two lists
keys = ["name", "age"]
values = ["John", 30]
person = {k: v for k, v in zip(keys, values)}Common Patterns
Counting with dictionaries
code.pyPython
# Manual counting
text = "hello"
counts = {}
for char in text:
counts[char] = counts.get(char, 0) + 1
# {'h': 1, 'e': 1, 'l': 2, 'o': 1}
# Using Counter (preferred)
from collections import Counter
counts = Counter(text)
counts.most_common(2) # [('l', 2), ('h', 1)]Grouping with dictionaries
code.pyPython
# Manual grouping
words = ["apple", "bat", "car", "ant", "bee"]
by_letter = {}
for word in words:
first = word[0]
by_letter.setdefault(first, []).append(word)
# {'a': ['apple', 'ant'], 'b': ['bat', 'bee'], 'c': ['car']}
# Using defaultdict (preferred)
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)Nested dictionaries
code.pyPython
users = {
"user1": {"name": "Alice", "age": 25},
"user2": {"name": "Bob", "age": 30}
}
# Access nested values
users["user1"]["name"] # "Alice"
# Safe nested access
users.get("user3", {}).get("name", "Unknown")Performance
| Operation | Average Case | Worst Case |
|---|---|---|
| Get item | O(1) | O(n) |
| Set item | O(1) | O(n) |
| Delete item | O(1) | O(n) |
| Iterate | O(n) | O(n) |
| Contains (in) | O(1) | O(n) |
Worst case occurs with hash collisions (rare with good hash functions).
Interview Tip
When asked about Python dictionaries:
- Explain hash table implementation with O(1) lookups
- Keys must be immutable (hashable)
- Since Python 3.7, dictionaries maintain insertion order
- Use
get()for safe access,setdefault()for defaults - Know Counter and defaultdict from collections
- Dictionary comprehensions for concise creation