我非常喜欢用字典来格式化字符串。它帮助我阅读我正在使用的字符串格式,以及让我利用现有的字典。例如:

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()

但是我搞不懂python。X语法来做同样的事情(或者如果可能的话)。我想做以下事情

# 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)

print("{latitude} {longitude}".format(**geopoint))

要将字典解压缩为关键字参数,请使用**。此外,new-style格式支持引用对象和映射项的属性:

'{0[latitude]} {0[longitude]}'.format(geopoint)
'The title is {0.title}s'.format(a) # the a from your first example

这对你有好处吗?

geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))

Python 2语法在Python 3中也适用:

>>> class MyClass:
...     def __init__(self):
...         self.title = 'Title'
... 
>>> a = MyClass()
>>> print('The title is %(title)s' % a.__dict__)
The title is Title
>>> 
>>> path = '/path/to/a/file'
>>> print('You put your file here: %(path)s' % locals())
You put your file here: /path/to/a/file

由于Python 3.0和3.1是EOL'ed的,没有人使用它们,你可以并且应该使用str.format_map(mapping) (Python 3.2+):

类似于str.format(**mapping),只不过映射是直接使用的,而不是复制到字典中。例如,如果mapping是dict子类,这就很有用。

这意味着你可以使用一个defaultdict,它会为缺少的键设置(并返回)一个默认值:

>>> 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'

即使提供的映射是字典,而不是子类,这可能仍然会稍微快一些。

不过,考虑到这一点,差异并不大

>>> d = dict(foo='x', bar='y', baz='z')

然后

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)

大约10 ns(2%)比

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)

我的Python 3.4.3。当字典中有更多键时,差异可能会更大


注意,格式语言比这灵活得多;它们可以包含索引表达式,属性访问等等,所以你可以格式化整个对象,或者其中的两个:

>>> 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'

从3.6开始,你也可以使用插值字符串:

>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'

您只需要记住在嵌套的引号中使用其他引号字符。这种方法的另一个优点是它比调用格式化方法快得多。


由于这个问题是特定于Python 3的,这里使用了新的f-string语法,从Python 3.6开始可用:

>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091

注意外单引号和内双引号(也可以反过来写)。


大多数答案只格式化字典的值。

如果你也想将键格式化为字符串,你可以使用dict.items():

geopoint = {'latitude':41.123,'longitude':71.091}
print("{} {}".format(*geopoint.items()))

输出:

('latitude', 41.123) ('longitude', 71.091)

如果你想以一种任意的方式格式化,也就是说,不像元组那样显示键值:

from functools import reduce
print("{} is {} and {} is {}".format(*reduce((lambda x, y: x + y), [list(item) for item in geopoint.items()])))

输出:

纬度是41.123,经度是71.091


geopoint = {'latitude':41.123,'longitude':71.091}

# working examples.
print(f'{geopoint["latitude"]} {geopoint["longitude"]}') # from above answer
print('{geopoint[latitude]} {geopoint[longitude]}'.format(geopoint=geopoint)) # alternate for format method  (including dict name in string).
print('%(latitude)s %(longitude)s'%geopoint) # thanks @tcll

使用format_map来做你想做的事情

print('{latitude} {longitude}'.format_map(geopoint))

这样做的好处是

字典不需要被分解成参数(与**地理点相比) 格式字符串只能访问所提供的映射,而不能访问变量的整个范围(与f -string相比)。