'How to use a dot in Python format strings?
I want to format a string and be able to use the dot operator, so that I can construct template strings containing e.g. {user.name}
, {product.price}
.
I tried this:
'Hello {user.name}'.format( {'user': { 'name': 'Markus' } } )
KeyError: 'user'
'Hello {user.name}'.format( **{'user': { 'name': 'Markus' } } )
AttributeError: 'dict' object has no attribute 'name'
Is there a way to do it?
Solution 1:[1]
Python dict
objects are unfortunately not attribute accessible (i.e. with the dot notation) by default. So you can either resign yourself to the uglier brackets notation:
'Hello {user[name]}'.format( **{'user': { 'name': 'Markus' } } )
Or you can wrap your data in a dot-accessible object. There are a handful of attribute-accessible dictionary classes you can install from PyPI, such as stuf.
from stuf import stuf
'Hello {user.name}'.format( **stuf({'user': { 'name': 'Markus' } }) )
I tend to keep my collections in stuf
objects so that I can easily access them by attribute.
Solution 2:[2]
The minimal change is to use square brackets in your template, rather than a period:
# v Note
>>> 'Hello {user[name]}'.format(**{'user': {'name': 'Markus'}})
'Hello Markus'
Alternatively, put objects that actually have that attribute in the dictionary, e.g. a custom class or collections.namedtuple
:
>>> class User(object):
def __init__(self, name):
self.name = name
>>> 'Hello {user.name}'.format(**{'user': User('Markus')})
'Hello Markus'
Note also that if you're writing out the literal you can just use a keyword argument:
>>> 'Hello {user.name}'.format(user=User('Markus'))
'Hello Markus'
Solution 3:[3]
Flatten the dictionary using comprehension....
def flatten_dict(dd, separator='>', prefix=''):
return {
prefix + separator + k if prefix else k : v
for kk, vv in dd.items()
for k, v in flatten_dict(vv, separator, kk).items()
} if isinstance(dd, dict) else { prefix : dd }
A call like this:
x = { 'A':1, 'B':{'C':2}}
y = flatten_dict(x)
Produces:
y = { 'A':1, 'B>C':2}}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Jonathan Eunice |
Solution 2 | jonrsharpe |
Solution 3 | Paul Kenjora |