dict.setdefault()

dict.setdefault(key[, default])
Returns: any · Updated March 13, 2026 · Dict Methods
dictionaries methods insertion default-values

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

ParameterTypeDefaultDescription
keyanyRequiredThe key to look up or insert into the dictionary
defaultanyNoneThe 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

MethodInserts Default?Use Case
.get(key, default)No - just retrievesSafe lookup without modification
.setdefault(key, default)Yes - inserts if missingLookup + initialize in one step
dict[key]No - raises KeyErrorWhen 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