необязательное пространство в форматировании строк python
Предположим, у меня есть 3 строки python, и я могу отформатировать все 3 из них с 2 разделяющими пробелами между ними, как в следующем:
h="hello"
m="my"
w="world"
print("{} {} {}".format(h,m,w))
или через
print("%s %s %s" % (h,m,w))
предположим теперь, что я уверен, что h и w имеют значения, но m может быть пустой строкой. Два фрагмента кода выше приведут к "hello{two speces here}world
.
Я знаю, что могу использовать различные функции и условные выражения для форматирования по коду, например в
print(h+" " + m+(" " if len(m)>0 else "") + w)
или выберите другую строку форматирования
print(("{} {} {}" if len(m)>0 else "{}{} {}").format(h,m,w))
на основе длины м.
мой Q-это можно сделать с помощью строки форматирования ? (например, некоторый модификатор формата, который будет заполняться 1 пробелом, если его параметр не пуст).
5 ответов
не уверен, что это очень удобно, но есть способ, генерирующий пространство или нет в зависимости от значения "истинности" строк:
h="hello"
m="my"
w="world"
print("{}{}{}{}".format(h," "*bool(m),m,w))
результат:
hello my world
сейчас поставил m
чтобы очистить строку, вы получаете
hello world
Я не уверен, что это можно сделать с помощью строк форматирования.
Я бы сделал это с python строка присоединиться.
strings = [h, m, w]
print " ".join([s for s in strings if len(s)>0])
внутренняя часть [s for s in strings if len(s)>0]
создает список только со строками ненулевой длины. Тогда " ".join(...)
соединяет их вместе с пробелом между ними.
Я считаю, что это невозможно с помощью строк форматирования в одиночку.
если вам нужно использовать строки форматирования, вы можете использовать модуль re, чтобы избавиться от дополнительных пробелов после применения форматирования:
import re
h="hello"
m="my"
w="world"
p = re.compile('\s+')
print p.sub(" ","{} {} {}".format(h,m,w))
что бы выход:
hello my world
С пустой строкой:
print p.sub(" ","{} {} {}".format(h,"",w))
выводит:
hello world
это то, что вы после?
Я приму ответ @Jean-François Fabre, который в основном отвечает на мой вопрос, как я его указал, сказав, что (по крайней мере, сейчас) нет ответа на это используя только форматирование строк (т. е. если переменные, которые будут сформированы, просто h, m & w без дополнительной обработки).
однако, используя концепцию булевых операторов на строках, как в его ответе, я думаю, что буду использовать:
print("{}{}{} {}".format(h,m and " " ,m , w))
это имеет недостаток давать человеку читая его чувствуя, что формируются 4 значения (что имеет место технически, но не семантически), но я думаю, что краткость и простота выражений здесь преодолевают отрицательный аспект.
читаемость может быть еще улучшена с помощью параметризованных форматов, как предложено @Tsingyi, но с использованием следующего:
print("{}{pad}{} {}".format(h, m , w, pad = m and " "))
Примечание:
НА МОМЕНТ НАПИСАНИЯ СТАТЬИ НЕ РАБОТАЕТ СЛЕДУЮЩИЙ КОД:
Надеюсь, в будущем, возможно, мы могли бы сделать что-то подобное:
print("{}{: >?} {}".format(h,m,w))
с семантикой "необязательно (если m тогда) выровнять его справа и площадку с одним дополнительным пространством слева", или
print("{} {: <?}{}".format(h,m,w))
с семантикой "необязательно (если m тогда) выровняйте его слева и поместите с одним дополнительным пространством справа"
подобные варианты могут быть полезны для дополнительного форматирования символов валюты например,
print("{:$>?}{}".format(s))
чтобы получить либо пустую строку, либо $123
одно последнее (длинное) Примечание: на в какой-то момент во время моего исследования этой проблемы я подумал, что смогу сделать что-то вроде этого:
def extend_string_formatting():
try:
'{:left-pad-if-not-empty}'.format('')
except ValueError:
original_formatter=str.__format__
def extended_formatter(self, format):
if (format == 'left-pad-if-not-empty'):
return ' ' + self if self else ''
return original_formatter(self, format)
str.__format__=extended_formatter
extend_string_formatting()
но оказывается, что это приводит к:
Traceback (most recent call last):
File "<input>", line 3, in extend_string_formatting
ValueError: Invalid format specifier
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 12, in extend_string_formatting
TypeError: can't set attributes of built-in/extension type 'str'
может быть, этого можно достичь, используя что-то вроде того, что описано здесь: https://stackoverflow.com/a/15975791/25412
можно использовать параметризованных форматы С Новым форматированием строки стиля, но вам все равно нужно проверить, является ли m
пусто или не самостоятельно.
def fmt(h, m, w):
return return '{}{:>{wd}} {}'.format(h, m, w, wd=len(m)+1 if m else 0)
>>> fmt('hello', 'my', 'world')
'hello my world'
>>> fmt('hello', '', 'world')
'hello world'