dict.setdefault()
dict.setdefault(key[, default]) any · Updated March 13, 2026 · Dict Methods The .setdefault() method returns the value for a key. If the key does not exist, it inserts the key with the specified default value and returns that default. This is particularly useful when you need to retrieve a value while ensuring it exists in the dictionary, all in a single operation.
Syntax
dict.setdefault(key[, default])
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
key | any | Required | The key to look up or insert into the dictionary |
default | any | None | The value to insert if the key does not exist. If omitted, defaults to None |
Return Value
Returns the value associated with key. If the key was not present, returns default (which defaults to None if not provided).
Basic Examples
Retrieving an existing value
When the key exists, .setdefault() returns the existing value without modifying the dictionary:
person = {"name": "Alice", "age": 30}
result = person.setdefault("name", "Unknown")
print(result)
# 'Alice'
print(person)
# {'name': 'Alice', 'age': 30} # unchanged
Inserting a missing key
When the key doesn’t exist, it inserts the default and returns it:
config = {"host": "localhost", "port": 8080}
result = config.setdefault("timeout", 30)
print(result)
# 30
print(config)
# {'host': 'localhost', 'port': 8080, 'timeout': 30}
Using with None as default
If you omit the default, it uses None:
data = {"key": "value"}
result = data.setdefault("new_key")
print(result)
# None
print(data)
# {'key': 'value', 'new_key': None}
Common Patterns
Initializing nested dictionaries
A powerful use case is building nested structures lazily:
# Build a nested dict of lists
grouped = {}
words = ["apple", "banana", "apricot", "blueberry", "blackberry"]
for word in words:
first_letter = word[0]
grouped.setdefault(first_letter, []).append(word)
print(grouped)
# {'a': ['apple', 'apricot'], 'b': ['banana', 'blueberry', 'blackberry']}
Counting with setdefault
An alternative to .get() for counting:
word_counts = {}
text = "the quick brown fox jumps over the lazy dog the fox"
for word in text.split():
word_counts.setdefault(word, 0)
word_counts[word] += 1
print(word_counts)
# {'the': 2, 'quick': 1, 'brown': 1, 'fox': 2, 'jumps': 1,
# 'over': 1, 'lazy': 1, 'dog': 1}
Caching with automatic initialization
cache = {}
def get_user(user_id):
# If user not in cache, initialize with default structure
if user_id not in cache:
cache.setdefault(user_id, {"data": None, "hits": 0})
cache[user_id]["hits"] += 1
return cache[user_id]
print(get_user(1))
# {'data': None, 'hits': 1}
print(get_user(1))
# {'data': None, 'hits': 2}
Merging dictionaries with conflict handling
defaults = {"theme": "dark", "language": "en", "debug": False}
user_config = {"theme": "light"}
# Apply defaults, but preserve existing user settings
for key, value in defaults.items():
user_config.setdefault(key, value)
print(user_config)
# {'theme': 'light', 'language': 'en', 'debug': False}
Default factory pattern
# Using setdefault for a simple default factory
records = []
def record_action(action, user):
# Initialize user entry if needed
records.append({"action": action, "user": user})
user_data.setdefault(user, []).append(action)
user_data = {}
record_action("login", "alice")
record_action("view", "bob")
record_action("edit", "alice")
print(user_data)
# {'alice': ['login', 'edit'], 'bob': ['view']}
setdefault() vs get() vs Bracket Notation
| Method | Inserts Default? | Use Case |
|---|---|---|
.get(key, default) | No - just retrieves | Safe lookup without modification |
.setdefault(key, default) | Yes - inserts if missing | Lookup + initialize in one step |
dict[key] | No - raises KeyError | When you’re certain key exists |
When to use each
Use .setdefault() when:
- You need to retrieve a value and create it if missing in one atomic operation
- Building nested structures or collections keyed by values
- You want cleaner code than the get-then-assign pattern
Use .get() when:
- You only want to read, not modify the dictionary
- You’re certain the key exists and just want a safe fallback
Use bracket notation when:
- Missing keys should be an error
- You’re certain the key exists
See Also
- dict.get() — safely retrieve values from a dictionary with defaults (without insertion)
- dict.fromkeys() — create a dictionary with all keys set to the same default value
- collections module — contains defaultdict for automatic default value creation on missing keys