繁体   English   中英

如何在 python-3.x 中使用字典格式化字符串?

[英]How do I format a string using a dictionary in python-3.x?

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

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 3.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)

这对你有好处吗?

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

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

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

由于 Python 3.0 和 3.1 已停产并且没有人使用它们,因此您可以并且应该使用str.format_map(mapping) (Python 3.2+):

类似于str.format(**mapping)除了直接使用映射而不是复制到dict 如果例如映射是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'

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

差异不大,但鉴于

>>> 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 上。 随着字典中的键越多,差异可能会越大,并且


请注意,格式语言比这灵活得多; 它们可以包含索引表达式、属性访问等,因此您可以格式化整个对象,或其中的 2 个:

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

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

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

由于该问题特定于 Python 3,因此这里使用自 Python 3.6 起可用的新 f-string 语法

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

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

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

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

如果您还想将密钥格式化为字符串,您可以使用dict.items()

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

输出:

('纬度', 41.123) ('经度', 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

使用 format_map 做你想做的事

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

这样做的好处是

  • 字典不必被分解成参数(与**geopoint相比)并且
  • 格式字符串只能访问提供的映射,而不能访问整个变量范围(与 F 字符串相比)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM