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

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

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

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

John,,Doe

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


person void.pointer    schedule 13.06.2012    source источник


Ответы (4)


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

from collections import defaultdict

my_csv = '{d[first]},{d[middle]},{d[last]}'
print( my_csv.format( d=defaultdict(str, first='John', last='Doe') ) )
person Andrew Clark    schedule 13.06.2012
comment
Я вижу, вы используете str. Что это? Изменить: теперь я вижу, что это фабричный метод, а не имя переменной. Таким образом, фабрика создаст пустые строки. - person void.pointer; 14.06.2012

"It does{cond} contain the the thing.".format(cond="" if condition else " not")

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

person roundar    schedule 24.07.2017
comment
Этот код помог мне, я искал способ распечатать список строк, где некоторые из них имеют заполнители, которые я хотел бы заменить константой. Поэтому я искал способ использовать string.format, чтобы он не жаловался на строки, в которых нет заполнителей; string.format (условие = значение) - person Vikas Putcha; 18.07.2018

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

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
person martineau    schedule 13.06.2012

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

>>> 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, я думаю, что добавлю эту поддержку.

person 0dminnimda    schedule 06.09.2020
comment
хотя вопрос был задан более 8 лет назад, я думаю, что это может помочь другим людям, у которых есть эта проблема. - person 0dminnimda; 06.09.2020
comment
Ваш не точно то, что я просил; заполнители должны быть удалены, если они не были заменены. - person void.pointer; 07.09.2020
comment
@void.pointer, это не проблема, в библиотеке также есть функция, чтобы удовлетворить это, я отредактировал ответ - person 0dminnimda; 07.09.2020
comment
по секрету скажем, если бы вы перешли по ссылке библиотеки, то вы бы увидели пример такого поведения на стартовой странице - person 0dminnimda; 07.09.2020
comment
хотя библиотека молода, ее функциональность будет продолжать расти. всегда будут новые идеи. (У меня уже есть некоторые идеи по поведению новых форматтеров) - person 0dminnimda; 07.09.2020
comment
подскажите стоит ли добавить поддержку 2.7? - person 0dminnimda; 07.09.2020