使用关键字解包格式化defaultdict **

时间:2014-03-07 09:45:51

标签: python dictionary default string-formatting

我想使用关键字解包运算符**格式化和打印字典中的数据。

格式字符串可能引用许多关键字,而字典可能没有所有必需的键。对于缺少的键,我想使用字符串'N / A'作为默认值。

我想为这个默认问题提供一个聪明的解决方案,可能使用defaultdict

以下是使用常规dict的第一个解决方案。

# Cumbersome solution with dict
format_str = '{date} {version} {comment}'
data       = dict()

data['date']    = 'today'
data['version'] = 'v1'
data['comment'] = 'N/A'  # I want to avoid this

print format_str.format(**data)
# prints: today v1 N/A

我想避免为缺失的密钥明确指定'N / A'。

以下解决方案还使用常规dict并分析格式字符串以构建关键字列表:

# Another solutions with handmade defaults for missing keys
format_str = '{date} {version} {comment}'
data       = dict()

data['date']    = 'today'
data['version'] = 'v1'

import re
for k in re.findall('{(\w+)}', format_str):
    if k not in data:
        data[k] = 'N/A'

print format_str.format(**data)
# prints: today v1 N/A

这个带有re.findall的解决方案并不优雅也不健壮,因为格式字符串的语法比上面的{(\w+)}复杂得多。

以下解决方案将是我最喜欢的解决方案......如果它没有因为一个明显的原因而失败。

# Failed attempt with defaultdict
from collections import defaultdict
format_str = '{date} {version} {comment}'
data       = defaultdict(lambda x:'N/A')

data['date']    = 'today'
data['version'] = 'v1'

print format_str.format(**data)
# raises KeyError: 'comment'

这里的问题是**实际上解包了data中的关键字,因此format不会搜索data所请求的关键字,因此不会{{1}提供默认值的机会。

有解决方案吗? 例如,是否有一个替代data函数实际上会调用format从而获得data.get(kwd) s?

2 个答案:

答案 0 :(得分:3)

使用string.Formatter.vformat()并将defaultdict传递给它。

from collections import defaultdict
from string import Formatter

fmtr = Formatter()
format_str = '{date} {version} {comment}'
data = defaultdict(lambda: 'N/A')

data['date'] = 'today'
data['version'] = 'v1'

print fmtr.vformat(format_str, (), data)

答案 1 :(得分:-1)

已经给出了使用格式化程序的好解决方案

但是,在这种情况下,您无法从关键字解包中受益。您必须以格式字符串指定要打印的键。

format_str = '{date} {version} {comment}'

dict按预期保留了关键字 - 值映射

所以对于像这样的词典

>>> d
{'version': 'v1', 'date': 'today'}

使用默认值dict.get()

>>> print '{} {} {}'.format(d['date'],d['version'],d.get('comment','n/a'))
today v1 n/a

如果您想在一个地方进行密钥管理(就像您使用格式字符串一样),我会尝试这样的事情

>>> f=lambda x: (x.get('date'),x.get('version'),x.get('comment','N/A'))
>>> print '{} {} {}'.format(*f(d))
today v1 N/A

或者

>>> f=lambda x: '{} {} {}'.format(x['date'],x['version'],x.get('comment','N/A'))
>>> print f(d)
today v1 N/A

好处是,减少进口