python:defaultdict不使用字符串格式

时间:2016-03-29 00:34:55

标签: python dictionary string-formatting default-value

这很容易:

'foo {bar}'.format(**{'bar': 0})

这不起作用,产生KeyError

from collections import defaultdict
d = defaultdict(int)
'foo {bar}'.format(**d)

有没有办法在字符串格式中容纳defaultdict

4 个答案:

答案 0 :(得分:6)

**解包会生成dict,这就是为什么这不起作用。如果您正在运行Python 3.2或更高版本,则可以将defaultdict传递给str.format_map,而不是为了传递非dict映射类型而存在的plunkr

'foo {bar}'.format_map(d)

修改:显然,至少在Python 3.5中,'foo {bar}'.format(**d)实际上可以使用defaultdict(int),并且d已被修改(格式化之后, reprdefaultdict(<class 'int'>, {'bar': 0})),因此在现代Python中,format_map的子类可能不需要dict。有趣。

答案 1 :(得分:1)

给出另一个答案,并在评论中,显然 在Python3中工作,但在Python2中你需要做一些更多的hackish:

from string import Formatter
from collections import defaultdict

mystring = 'foo {bar}'
d = defaultdict(int)
parts = Formatter().parse(mystring)
newstring = mystring.format(**{part[1]: d[part[1]] for part in parts})

答案 2 :(得分:1)

基于@zondo's answer(在很小程度上,@ShadowRanger's),您可以执行类似这样的操作,这对我来说在Python 2.7.11和3.5.1中都能正常工作。

from string import Formatter
from collections import defaultdict

def string_format_map(fmt, d):
    try:
        str.format_map
    except AttributeError:
        parts = Formatter().parse(fmt)
        return fmt.format(**{part[1]: d[part[1]] for part in parts})
    else:
        return fmt.format(**d)

d = defaultdict(int)
print(string_format_map('foo {bar}', d))

答案 3 :(得分:0)

您不需要预先解析格式字符串:您可以直接使用vformat的{​​{1}}方法:

Formatter

该输出字符串有7个空格,如格式字符串所指定。