I’ve recently stumbled upon str.format_map
method in Python and this short article describes how it works and how it differs from str.format
.
format
method
format
string method allows for substituting placeholders (constructed by using {}
) within string with the values provided by the caller, i.e.:
>>> tmpl1 = "first_name: {} | last_name: {}"
>>> tmpl1.format("John", "Doe")
'first_name: John | last_name: Doe'
Bare {}
placeholders will be substituted with positional arguments passed to format
method.
You could also add numbers to placeholders and they’ll be used for accessing positional arguments by index. This also lets you use one value in multiple place of the template (without repeating it as an argument):
>>> tmpl2 = "first_name: {0} | last_name: {1}"
>>> tmpl2.format("John", "Doe")
'first_name: John | last_name: Doe'
>>> tmpl3 = "first_name: {0} | last_name: {1} | last_name: {1}"
>>> tmpl3.format("John", "Doe")
'first_name: John | last_name: Doe | last_name: Doe'
You can also “name” your placeholders and keywords arguments/unpacked dictionary for passing substitution values:
>>> tmpl4 = "first_name: {first_name} | last_name: {last_name}"
>>> tmpl4.format(first_name="John", last_name="Doe")
'first_name: John | last_name: Doe'
>>> tmpl4.format(**{"first_name": "John", "last_name": "Doe"})
'first_name: John | last_name: Doe'
When supplying a dictionary, it must contain all keys from the template. Otherwise, KeyError
is thrown:
>>> tmpl4.format(**{"first_name": "John"})
...
KeyError: 'last_name'
format_map
and how it’s different from format
?
Similarly to format
method, format_map
allows for substitution of placeholders in the string with given values. formap_map
accepts a single argument (mapping
):
>>> tmpl4.format_map({"first_name": "John", "last_name": "Doe"})
'first_name: John | last_name: Doe'
The difference between
tmpl4.format(**{"first_name": "John", "last_name": "Doe"})
and
tmpl4.format_map({"first_name": "John", "last_name": "Doe"})
is that format(**some_dict)
operates on a copy of dictionary while format_map(some_dict)
does not create a new copy of some_dict
dictionary.
The other difference in their behaviours is that format_map
works with subclasses of dict
class. It allows for customizing the behaviour of missing key - by implementing __missing__
dunder method.
Let’s create such class:
class Person(dict):
def __missing__(self, key):
return "N/A"
>>> p1 = Person(first_name="John")
>>> p1["first_name"]
'John'
>>> p1["last_name"]
'N/A'
>>> tmpl4.format_map(p1)
'first_name: John | last_name: N/A'
Even though p1
object was not initialized with last_name
value, format_map
did not raise any error and used the result of custom missing key behaviour when substituting value for {last_name}
placeholder.
(3/52) This is a 3rd post for my blogging challenge (publishing 52 posts in 2024).