string.format() с необязательными заполнителями

У меня есть следующий код Python (я использую Python 2.7.X):

my_csv = '{first},{middle},{last}'
print( my_csv.format( first='John', last='Doe' ) )

Я получаю KeyError исключение, потому что 'middle' не указано (это ожидается). Однако я хочу, чтобы все эти заполнители были необязательными. Если эти именованные параметры не указаны, я ожидаю, что заполнители будут удалены. Таким образом, строка, напечатанная выше, должна быть:

John,,Doe

Есть ли встроенная функциональность, чтобы сделать эти заполнители необязательными, или требуется более глубокая работа? Если последнее, если кто-то может показать мне самое простое решение, я буду признателен!

3 ответа

Решение

Вот один из вариантов:

from collections import defaultdict

my_csv = '{d[first]},{d[middle]},{d[last]}'
print( my_csv.format( d=defaultdict(str, first='John', last='Doe') ) )
"It does{cond} contain the the thing.".format(cond="" if condition else " not")

Думаю, что я добавлю это, потому что это была функция с тех пор, как был задан вопрос, вопрос по-прежнему всплывает рано в результатах Google, и этот метод встроен непосредственно в синтаксис Python (не требует импорта или пользовательских классов). Это простое условное утверждение. Они интуитивно понятны для чтения (когда они просты), и часто полезно, чтобы они закорачивали.

Вот еще один вариант, который использует оператор интерполяции строк %:

class DataDict(dict):
    def __missing__(self, key):
        return ''

my_csv = '%(first)s,%(middle)s,%(last)s'
print my_csv % DataDict(first='John', last='Doe')  # John,,Doe

В качестве альтернативы, если вы предпочитаете использовать более современный str.format() метод, следующее также будет работать, но будет менее автоматическим в том смысле, что вам придется явно определять все возможные заполнители заранее (хотя вы можете изменить DataDict.placeholders на лету при желании):

class DataDict(dict):
    placeholders = 'first', 'middle', 'last'
    default_value = ''
    def __init__(self, *args, **kwargs):
        self.update(dict.fromkeys(self.placeholders, self.default_value))
        dict.__init__(self, *args, **kwargs)

my_csv = '{first},{middle},{last}'
print(my_csv.format(**DataDict(first='John', last='Doe')))  # John,,Doe

Я столкнулся с той же проблемой, что и ваша, и решил создать библиотеку для решения этой проблемы: пиформатирование.
Вот решение вашей проблемы с пиформатированием:

>>> from pyformatting import defaultformatter
>>> default_format = defaultformatter(str)
>>> my_csv = '{first},{middle},{last}'
>>> default_format(my_csv, first='John', last='Doe')
'John,,Doe'

Единственная проблема заключается в том, что pyformatting не поддерживает python 2. Pyformatting поддерживает python 3.1+. Если я увижу какие-либо отзывы о необходимости поддержки 2.7, я думаю, что добавлю эту поддержку.

Другие вопросы по тегам