【问题标题】:Formatting a defaultdict with keyword unpacking **使用关键字解包格式化 defaultdict **
【发布时间】:2014-04-10 09:26:47
【问题描述】:

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

格式字符串可能引用了许多关键字,而字典可能没有所有必需的关键字。对于缺少的键,我想使用字符串 '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 中搜索请求的关键字,因此不会给data 提供其默认值的机会。

有解决办法吗? 例如,是否有一个替代的format 函数实际上会调用data.get(kwd) 并因此得到N/As?

【问题讨论】:

标签: python dictionary default string-formatting


【解决方案1】:

使用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)

【讨论】:

【解决方案2】:

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

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

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

好处是,减少进口

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-09
    • 2018-07-28
    • 2020-12-20
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多