How do I format a string using a dictionary in python-3.x?
Solution 1
Since the question is specific to Python 3, here's using the new f-string syntax, available since Python 3.6:
>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091
Note the outer single quotes and inner double quotes (you could also do it the other way around).
Solution 2
Is this good for you?
geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))
Solution 3
To unpack a dictionary into keyword arguments, use **
. Also,, new-style formatting supports referring to attributes of objects and items of mappings:
'{0[latitude]} {0[longitude]}'.format(geopoint)
'The title is {0.title}s'.format(a) # the a from your first example
Solution 4
As Python 3.0 and 3.1 are EOL'ed and no one uses them, you can and should use str.format_map(mapping)
(Python 3.2+):
Similar to
str.format(**mapping)
, except that mapping is used directly and not copied to adict
. This is useful if for example mapping is adict
subclass.
What this means is that you can use for example a defaultdict
that would set (and return) a default value for keys that are missing:
>>> from collections import defaultdict
>>> vals = defaultdict(lambda: '<unset>', {'bar': 'baz'})
>>> 'foo is {foo} and bar is {bar}'.format_map(vals)
'foo is <unset> and bar is baz'
Even if the mapping provided is a dict
, not a subclass, this would probably still be slightly faster.
The difference is not big though, given
>>> d = dict(foo='x', bar='y', baz='z')
then
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)
is about 10 ns (2 %) faster than
>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)
on my Python 3.4.3. The difference would probably be larger as more keys are in the dictionary, and
Note that the format language is much more flexible than that though; they can contain indexed expressions, attribute accesses and so on, so you can format a whole object, or 2 of them:
>>> p1 = {'latitude':41.123,'longitude':71.091}
>>> p2 = {'latitude':56.456,'longitude':23.456}
>>> '{0[latitude]} {0[longitude]} - {1[latitude]} {1[longitude]}'.format(p1, p2)
'41.123 71.091 - 56.456 23.456'
Starting from 3.6 you can use the interpolated strings too:
>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'
You just need to remember to use the other quote characters within the nested quotes. Another upside of this approach is that it is much faster than calling a formatting method.
Solution 5
print("{latitude} {longitude}".format(**geopoint))
Related videos on Youtube
Doran
Updated on June 18, 2021Comments
-
Doran almost 3 years
I am a big fan of using dictionaries to format strings. It helps me read the string format I am using as well as let me take advantage of existing dictionaries. For example:
class MyClass: def __init__(self): self.title = 'Title' a = MyClass() print 'The title is %(title)s' % a.__dict__ path = '/path/to/a/file' print 'You put your file here: %(path)s' % locals()
However I cannot figure out the python 3.x syntax for doing the same (or if that is even possible). I would like to do the following
# Fails, KeyError 'latitude' geopoint = {'latitude':41.123,'longitude':71.091} print '{latitude} {longitude}'.format(geopoint) # Succeeds print '{latitude} {longitude}'.format(latitude=41.123,longitude=71.091)
-
Homunculus Reticulli almost 12 yearsTried this and it worked. But I don't understand the use of the 'pointer notation'. I know Python doesn't use pointers, is this an example of kwargs?
-
D.Rosado almost 12 years@HomunculusReticulli That is a format parameter (Minimum field width), not a pointer to a pointer C++ style. docs.python.org/release/2.4.4/lib/typesseq-strings.html
-
diapir over 9 yearsPython 3.2 introduced
format_map
. Similar tostr.format(**mapping)
, except thatmapping
is used directly and not copied to adict
. This is useful if for examplemapping
is a dict subclass -
Bhargav Rao about 8 yearsNice one, Is there any performance improvements over
format
? (Given that it is not copied to a dict) -
Antti Haapala -- Слава Україні about 8 years@BhargavRao not much, 2 % :D
-
Løiten over 7 yearsI find this answer better, as adding the positional index for the placeholder makes the code more explicit, and easier to use. Especially if one has something like this:
'{0[latitude]} {1[latitude]} {0[longitude]} {1[longitude]}'.format(geopoint0, geopoint1)
-
Whymarrh over 7 yearsThis is useful if you're using a
defaultdict
and don't have all the keys -
Nityesh Agarwal about 7 years@eugene What does ** do to a python dictionary? I don't think that it creates an object because print(**geopoint) fails giving syntax error
-
abhisekp about 7 years@NityeshAgarwal it spreads the dictionary with the name=value pairs as individual arguments i.e.
print(**geopoint)
is same asprint(longitude=71.091, latitude=41.123)
. In many languages, it is known as splat operator. In JavaScript, it's called spread operator. In python, there is no particular name given to this operator. -
Jonatas CD almost 6 yearsI would say that use of the f-string is more aligned to python3 approach.
-
Samie Bencherif over 5 years@NityeshAgarwal new to me too. it's pretty cool.
-
Hugo over 4 yearsKeep in mind that f-strings are new to Python 3.6, and not in 3.5.
-
Tcll about 4 yearsplus it's also noticably more performant than
f""
or"".format()
;) -
Tcll about 4 yearsyou missed one ;)
print('%(latitude)s %(longitude)s'%geopoint)
this is also significantly faster than the other 2 -
Tcll about 4 yearsnote there's a chance 'longitude' could come before 'latitude' from
geopoint.items()
;) -
Tcll about 4 years@BhargavRao if you're looking for performance, use this
'%(latitude)s %(longitude)s'%geopoint
;) -
Sheikh Abdul Wahid about 4 years@tcll Actually I wanted the examples, where I can use the dictionary name inside the string. Something like this
'%(geopoint["latitude"])s %(geopoint["longitude"])s'%{"geopoint":geopoint}
-
JohnMudd over 3 yearsThanks! I don't know why this doesn't have more votes.
-
Aleksandr Panzin about 3 yearsThis is the simplest option, TBH. It's also the similar way as you transform a list to varargs. This should be the way.