我想要打印一个带有冒号的字典。不幸的是冒号字符用于格式化,所以我需要以某种方式逃避它。
例如:
>>> d = {'hello': 'world', 'with:colon': 'moo'}
>>> '{hello}'.format(**d)
'world'
>>> '{with:colon}'.format(**d)
KeyError: 'with'
>>> '{with\:colon}'.format(**d)
KeyError: 'with\\'
>>> '{with::colon}'.format(**d)
KeyError: 'with'
答案 0 :(得分:10)
根据the documentation,你要问的是根本不可能的。具体地,
由于arg_name不是引号分隔的,因此无法在格式字符串中指定任意字典键(例如,字符串
'10'
或':-]'
)。
答案 1 :(得分:6)
作为解决方法:
>>> d = {'hello': 'world', 'with:colon': 'moo'}
>>> '{hello} {}'.format(d['with:colon'],**d)
'world moo'
>>> '{hello} {0}'.format(d['with:colon'],**d)
'world moo'
答案 2 :(得分:2)
你不能 - 键必须在语法上等同于Python标识符。请参阅文档中的Format String Syntax:
replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
arg_name ::= [identifier | integer]
attribute_name ::= identifier
答案 3 :(得分:2)
从python 3.6开始,您可以使用新的f-string格式化来解决这个问题:
>>> d = {'hello': 'world', 'with:colon': 'moo'}
>>> print(f"with:colon is equal to {d['with:colon']}")
with:colon is equal to moo
答案 4 :(得分:1)
正如@murgatroid99在他的回答中指出的那样,这是不可能的。
解决方法是用有效的键替换键:
d_sanitised = {key.replace(":", "-"): value for key, value in d.items()}
当然,如果可能与其他密钥发生冲突,您可能需要小心。
>>> d = {'hello': 'world', 'with:colon': 'moo'}
>>> d_sanitised = {key.replace(":", "-"): value for key, value in d.items()}
>>> '{with-colon}'.format(**d_sanitised)
'moo'
显然,这假设您可以修改格式字符串以适应。理想情况下,只需修改两端即可避免冒号。
答案 5 :(得分:1)
遗憾的是,内置格式化程序不允许这样做。一个明显的语法扩展是允许在必要时引用键。您的格式字符串将如下所示:
format('{"with:colon"} and {hello}'
幸运的是,扩展Formatter似乎很容易提供这种语法,这是一个POC实现:
class QuotableFormatter(string.Formatter):
def __init__(self):
self.super = super(QuotableFormatter, self)
self.super.__init__()
self.quotes = {}
def parse(self, format_string):
fs = ''
for p in re.findall(r'(?:".+?")|(?:[^"]+)', format_string):
if p[0] == '"':
key = '_q_' + str(len(self.quotes))
self.quotes[key] = p[1:-1]
fs += key
else:
fs += p
return self.super.parse(fs)
def get_field(self, field_name, args, kwargs):
if field_name.startswith('_q_'):
field_name = self.quotes[field_name]
return self.super.get_field(field_name, args, kwargs)
用法:
d = {'hello': 'world', 'with:colon': 'moo', "weird!r:~^20": 'hi'}
print QuotableFormatter().format('{"with:colon":*>20} and {hello} and {"weird!r:~^20"}', **d)
# *****************moo and world and hi