python字符串格式化中的可选空格

时间:2017-10-25 07:53:08

标签: python string-formatting

假设我有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))

基于m的长度。

我的问题是否可以使用 格式化字符串 来完成? (例如,如果参数不为空,将使用1个空格填充的某个格式修饰符。)

5 个答案:

答案 0 :(得分:5)

不确定它是否非常方便,但有一种方法,根据字符串的“真值”值产生空间或不产生空间:

h="hello"
m="my"
w="world"

print("{}{}{}{}".format(h," "*bool(m),m,w))

结果:

hello my world

现在将m设置为空字符串,你得到

hello world

答案 1 :(得分:3)

我不确定这可以通过格式化字符串来完成。

我会用python string join执行此操作。

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(...)将它们连接在一起。

答案 2 :(得分:2)

我认为单独使用格式化字符串是不可能的。

如果你必须使用格式化字符串,你可以使用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

这就是你想要的吗?

答案 3 :(得分:1)

我会接受@ Jean-FrançoisFabre的答案基本上回答我的问题,正如我所说的那样(至少现在)没有答案 仅使用字符串格式化(即,如果要格式化的变量只是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然后)将其对齐到左侧,并在其右侧增加一个空格”

类似的变体可能有助于货币符号的可选格式化 e.g。

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

答案 4 :(得分:0)

您可以将Parametrized formats用于新样式字符串格式,但您仍需要自己测试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'