str.format_map()

The reason it exists: format(**m) copies m into a new dict, so a custom mapping loses its behaviour. format_map passes the object through untouched.

String methodPython 3.2+Live demo
Common call
s.format_map(mapping)
Returns
str — the filled-in template
Replaces
format(**mapping), which flattens the mapping into a plain dict
Watch out
a missing key raises KeyError unless your mapping handles it
str.format_map(mappingmappingAny object supporting __getitem__ — a dict, a defaultdict, or a custom class. It is used directly, never copied.type: mapping · required)
str

Demo

Live evaluation
Try:
Inputs
templatestrtemplate with {placeholders}
mappingmappingkey:value pairs, comma separated
Output
'{name} is {age}'.format_map({'name': 'Ada', 'age': '36'})
'Ada is 36'

Each {key} is looked up in the mapping and replaced by the value. Keys the template never mentions are simply unused, and a key the template needs but the mapping lacks raises KeyError naming it. Everything here is also true of format(**mapping) — the difference only shows once the mapping is not a plain dict, because format copies it and format_map does not.

Parameters

NameTypeRequiredDescription
mappingmappingyesAny object supporting __getitem__ — a dict, a defaultdict, or a custom class. It is used directly, never copied.

Return value

strA new string with each {key} replaced by mapping[key]. Raises KeyError for a placeholder the mapping cannot supply.

Common patterns

Tolerate missing keys
A defaultdict survives the copy that format(**m) would make — this is the headline use.
from collections import defaultdict
s.format_map(defaultdict(str, name="Ada"))
Leave unknown placeholders alone
A mapping that returns the placeholder itself makes substitution partial and repeatable.
class Keep(dict):
    def __missing__(self, key):
        return "{" + key + "}"

s.format_map(Keep(name="Ada"))
Format straight from an object
Any __getitem__ works, so a live view of state needs no dict built first.
template.format_map(config)   # config[key] on demand

Examples

1. Two fields
'{name} is {age}'.format_map({'name': 'Ada', 'age': 36})
Returns
'Ada is 36'
2. Repeated key
'{x} and {x}'.format_map({'x': 'hi'})
Returns
'hi and hi'
3. Unused keys fine
'{a}'.format_map({'a': 1, 'b': 2})
Returns
'1'
4. Missing raises
'{a}'.format_map({'b': 1})
Returns
KeyError: 'a'
5. defaultdict fills
'{a}'.format_map(defaultdict(str))
Returns
''
6. format would copy
'{a}'.format(**defaultdict(str))
Returns
KeyError: 'a' # the copy lost it

Pitfalls

1. format(**mapping) silently loses custom behaviour
This is the whole point of the method. ** unpacks the mapping into a plain dict, so __missing__ and any laziness are gone before formatting starts — and the failure looks like the mapping did not work.
defaultdict defeated
from collections import defaultdict
'{a}'.format(**defaultdict(str))
KeyError: 'a'
Pass it through
'{a}'.format_map(defaultdict(str))
''
2. Never call it on untrusted templates
Format strings can reach attributes and items, so a hostile template can walk from a harmless value into internals. This is the same class of bug as untrusted format() strings.
Template injection
user_template.format_map(ctx)
a crafted template can read ctx internals
Fixed template
FIXED_TEMPLATE.format_map(user_values)
only the values come from outside
3. Literal braces still need doubling
format_map uses the same grammar as format, so a lone brace is a syntax error in the template rather than a literal character.
Unbalanced
'{a} }'.format_map({'a': 1})
ValueError: Single '}' encountered in format string
Double it
'{a} }}'.format_map({'a': 1})
'1 }'
4. It takes one positional argument, not keywords
format_map(name="Ada") is a TypeError. The mapping goes in as a single object — that is the difference from format, and an easy slip when converting between the two.
Keywords rejected
'{name}'.format_map(name='Ada')
TypeError: format_map() takes no keyword arguments
Pass a mapping
'{name}'.format_map({'name': 'Ada'})
'Ada'

When to use

Use it
  • The mapping is a defaultdict or defines __missing__
  • The mapping is large and copying it would be wasteful
  • Keys are computed lazily by a custom __getitem__
  • Keys are not valid Python identifiers, so ** cannot express them
Reach for something else
  • A plain dict with all keys present → format(**d) reads more familiarly
  • Templates from users → string.Template is far safer
  • Simple interpolation of local variables → an f-string

Notes

Complexity
O(len(template)) plus one mapping lookup per placeholder
Return
A new str; the template and the mapping are unchanged
CPython impl
Objects/unicodeobject.c :: unicode_format_map
Memory
Allocates the result only — unlike format(**m), no dict copy is made
Thread-safe
Depends on the mapping; the string side is immutable and safe

FAQ

Only in how the mapping arrives. ** unpacks it into a fresh plain dict, so anything special about the original — __missing__, laziness, non-identifier keys — is gone. format_map hands the object straight to the formatter, so all of that still works.

'{a}'.format_map(defaultdict(str))   # ''
'{a}'.format(**defaultdict(str))     # KeyError

History

3.2
str.format_map added, giving format access to a mapping without copying it.