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

Dor*_*ran 196 python string dictionary 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()
Run Code Online (Sandbox Code Playgroud)

但是,我无法弄清楚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)
Run Code Online (Sandbox Code Playgroud)

coc*_*omo 367

这对你有好处吗?

geopoint = {'latitude':41.123,'longitude':71.091}
print('{latitude} {longitude}'.format(**geopoint))
Run Code Online (Sandbox Code Playgroud)

  • Python 3.2引入了[`format_map`](https://docs.python.org/3.4/library/stdtypes.html#str.format_map)._类似于`str.format(**mapping)`,除了`mapping`直接使用而不是复制到`dict`.这很有用,例如`mapping`是一个dict子类_ (26认同)
  • @NityeshAgarwal它使用名称=值对作为单独的参数传播字典,即`print(**geopoint)`与`print(经度= 71.091,纬度= 41.123)`相同.在许多语言中,它被称为*splat operator*.在JavaScript中,它被称为*spread operator*.在python中,没有为此运算符指定特定名称. (3认同)
  • 试过这个并且它起作用了.但我不明白'指针符号'的使用.我知道Python不使用指针,这是kwargs的一个例子吗? (2认同)
  • @HomunculusReticulli这是一个格式参数(最小字段宽度),而不是指向C++样式的指针.http://docs.python.org/release/2.4.4/lib/typesseq-strings.html (2认同)

小智 77

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

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

  • 我发现此答案更好,因为为占位符添加位置索引会使代码更明确,并且更易于使用。特别是如果某人具有这样的内容:`'{0 [latitude]} {1 [latitude]} {0 [longitude]} {1 [longitude}}'。format(geopoint0,geopoint1)` (2认同)

Ant*_*ala 59

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

类似于str.format(**mapping),除了直接使用映射而不是复制到adict.如果例如mapping是dict子类,这将非常有用.

这意味着您可以使用例如defaultdict为缺少的键设置(并返回)默认值的a:

>>> 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'
Run Code Online (Sandbox Code Playgroud)

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

给出的差异并不大

>>> d = dict(foo='x', bar='y', baz='z')
Run Code Online (Sandbox Code Playgroud)

然后

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format_map(d)
Run Code Online (Sandbox Code Playgroud)

比快10秒(2%)快

>>> 'foo is {foo}, bar is {bar} and baz is {baz}'.format(**d)
Run Code Online (Sandbox Code Playgroud)

在我的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'
Run Code Online (Sandbox Code Playgroud)

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

>>> f'lat:{p1["latitude"]} lng:{p1["longitude"]}'
'lat:41.123 lng:71.091'
Run Code Online (Sandbox Code Playgroud)

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

  • @BhargavRao不多,2%:D (2认同)

S.L*_*ott 15

print("{latitude} {longitude}".format(**geopoint))
Run Code Online (Sandbox Code Playgroud)

  • 这是最简单的选择,TBH。这也与将列表转换为可变参数的方式类似。应该是这样。 (2认同)

Wyr*_*ood 8

由于这个问题是针对Python 3的,所以这里使用了新的f-string语法:

>>> geopoint = {'latitude':41.123,'longitude':71.091}
>>> print(f'{geopoint["latitude"]} {geopoint["longitude"]}')
41.123 71.091
Run Code Online (Sandbox Code Playgroud)

注意外部单引号和内部双引号(您也可以反过来这样做).

  • 请记住,f 字符串是 Python 3.6 中的新功能,而不是 3.5 中的新功能。 (2认同)

Len*_*bro 5

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
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 5

使用 format_map 来做你想做的事

print('{latitude} {longitude}'.format_map(geopoint))
Run Code Online (Sandbox Code Playgroud)

这样做的好处是

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