2013-12-16 2 views
6

Есть ли способ форматировать строку с помощью dict, но необязательно без ключевых ошибок?Строковый формат с опциональным значением ключа ключа

Это прекрасно работает:

opening_line = '%(greetings)s %(name)s !!!' 
opening_line % {'greetings': 'hello', 'name': 'john'} 

Но давайте говорить, что я не знаю имени, и я хотел бы форматировать выше линии только для 'greetings'. Нечто подобное,

opening_line % {'greetings': 'hello'} 

выход будет хорошо, даже если:

'hii %(name)s !!!' # keeping name un-formatted 

Но это дает KeyError при распаковке

Есть ли способ?

+0

** См. Также: ** [py str.fo rmat missing values] (https://stackoverflow.com/questions/20248355/how-to-get-python-to-gracefully-format-none-and-non-existing-fields) – dreftymac

ответ

10

Используйте defaultdict, это позволит вам указать значение по умолчанию для ключей, которых нет в словаре. Например:

>>> from collections import defaultdict 
>>> d = defaultdict(lambda: 'UNKNOWN') 
>>> d.update({'greetings': 'hello'}) 
>>> '%(greetings)s %(name)s !!!' % d 
'hello UNKNOWN !!!' 
>>> 
+5

Обратите внимание, что это не сработает с 'str.format'. – jonrsharpe

2

Некоторые чередуется к defaultDict,

greeting_dict = {'greetings': 'hello'} 

if 'name' in greeting_dict : 
    opening_line = '{greetings} {name}'.format(**greeting_dict) 
else: 
    opening_line = '{greetings}'.format(**greeting_dict) 

print opening_line 

Может быть, еще более лаконично, использование словаря получить установить в значениях параметров по умолчанию,

'{greetings} {name}'.format(greetings=greeting_dict.get('greetings','hi'), 
          name=greeting_dict.get('name','')) 
+0

Я бы выделил общность в 'if/else' и вместо этого' fmt = '{greetings} {name}' if 'name' в greeting_dict else '{greetings}'; печать (fmt.format (** greeting_dict)) '. –

1

Для записи:

info = { 
    'greetings':'DEFAULT', 
    'name':'DEFAULT', 
    } 
opening_line = '{greetings} {name} !!!' 

info['greetings'] = 'Hii' 
print opening_line.format(**info) 
# Hii DEFAULT !!! 
Смежные вопросы