Python 字符串格式化

字符串格式化


对于如何输出格式化的字符串,是一个常见的问题。有时需要对字符串进行对齐,或者按照指定的列宽格式化字符串,亦或是对字符串进行拼接,有时候还需要构造内嵌变量的字符串等。Python 提供了一些方法对上述情况进行实现。

ljust()、rjust()、center()


对于基本字符串对齐操作,可以使用字符串内置方法 ljust()rjust()center()。如下示例:

>>> text = "Hello World"
>>> text.ljust(20)
'Hello World         '
>>> text.rjust(20)
'         Hello World'
>>> text.center(20)
'    Hello World     '
>>>

上述三个方法有两个参数 widthfillcharwidth 用于返回长度为 width 的字符串,使用指定的 fillchar 填充空位(默认使用 ASCII 空格符,可指定其他字符)。

其中 ljust() 原字符串在其中靠左对齐,rjust() 靠右对齐,center() 在正中。

尝试使用指定非空格的 fillchar 作为填充字符,例如:

>>> text.ljust(20, '-')
'Hello World---------'
>>> text.rjust(20, '=')
'=========Hello World'
>>> text.center(20, '*')
'****Hello World*****'

这三个方法还有个特性,如果参数 width 小于等于 len(s) 字符串的长度,则返回原字符串的副本。

>>> len(text)
11
>>> text.ljust(11)
'Hello World'
>>> text.rjust(10)
'Hello World'
>>> text.center(9)
'Hello World'

format()


字符串对齐

除了使用上述三种方法对字符串进行对齐,format() 也能够实现对齐字符串。

各种对齐选项含义如下:

选项含义
‘<’强制字段在可用空间内向左对齐(大多数对象的默认值)
‘>’强制字段在可用空间内向右对齐(数字的默认值)
‘^’强制字段在可用空间内居中

使用 format() 对字符串进行对齐,在上述对齐选项后面添加指定宽度,示例如下:

>>> format(text, '>20')
'         Hello World'
>>> format(text, '<20')
'Hello World         '
>>> format(text, '^20')
'    Hello World     '

如果需要指定非空格填充字符,可在对齐选项前面添加 fill 字符,可以是任意字符。

>>> format(text, '->20')
'---------Hello World'
>>> format(text, '=<20')
'Hello World========='
>>> format(text, '*^20')
'****Hello World*****'

format() 可用于格式化多个值,比如:

>>> '{:>10s} {:>10s}'.format('Hello', 'World')
'     Hello      World'

s 为字符串表示类型,表示字符串格式,字符串的默认类型,可省略。

format() 不单只适用于字符串。它可以格式化任何值。例如,格式化数字:

>>> format(x, '>10')
'    1.2345'
>>> format(x, '^10.2f')
'   1.23   '

f 为浮点型表示类型,表示定点表示。其中 .2f 表示以 f 格式化的浮点数值在小数点后显示 2 个数位。

相比 ljust()rjust()center()format() 更通用,同时还可以格式化任意对象,不仅仅是字符串。

替换内嵌变量字符串

字符串的 format() 方法,能够用指定的值替换内嵌变量字符串中的变量。

>>> s = '{name} was born in {country}'
>>> s.format(name='Guido',country='Netherlands')
'Guido was born in Netherlands'

如果被替换的变量能够在变量域中找到,可以结合使用 format_map()vars()。示例如下:

>>> name = 'Guido'
>>> country = 'Netherlands'
>>> s.format_map(vars())
'Guido was born in Netherlands'
>>>

format()format_map() 有一个缺陷,不能很好处理变量缺失的情况,如下示例:

>>> s.format(name='Gudio')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'country'

这里可以使用 __missing__() 方法,定义一个含此方法的字典来避免上面发生的错误。例如:

>>> class Default(dict):
...     def __missing__(self, key):
...         return key
...
>>> s.format_map(Default(name='Gudio'))
'Guido was born in country'

若需完全了解 format() 函数的相关特性,请参考 Python文档

join()


若需合并的字符串是在一个序列或者 iterable 中,建议使用 join() 方法。示例如下:

>>> words = ['Hello', 'World']
>>> ' '.join(words)
'Hello World'
>>> ','.join(words)
'Hello,World'

join(iterable) 方法返回的是一个由 iterable 中的字符串拼接的字符串。如果 iterable 中存在任何非字符值包括 bytes 对象则会引发 TypeError。调用该方法的字符串将作为元素之间的分隔。例如上述例子的空格 ' '和 逗号 ','

还有一种拼接字符串的方法是用加号 +,但是这种效率通常是非常低的。这种加号连接会引起内存复制以及垃圾回收机制。不建议使用下列方法连接字符串:

s = ''
for word in words:
    s += word

textwrap


长字符串输出的时候,有时需要进行一定的格式化输出,如下示例:

>>> s = "The Zen of Python, by Tim Peters \
... Beautiful is better than ugly.\
... Explicit is better than implicit. \
... Simple is better than complex. \
... Complex is better than complicated. \
... Flat is better than nested. \
... Sparse is better than dense. \
... Readability counts. \
... Special cases aren't special enough to break the rules. \
... Although practicality beats purity. \
... Errors should never pass silently. \
... Unless explicitly silenced. \
... In the face of ambiguity, refuse the temptation to guess. \
... There should be one-- and preferably only one --obvious way to do it. \
... Although that way may not be obvious at first unless you're Dutch. \
... Now is better than never. \
... Although never is often better than *right* now. \
... If the implementation is hard to explain, it's a bad idea. \
... If the implementation is easy to explain, it may be a good idea. \
... Namespaces are one honking great idea -- let's do more of those!"

>>> import textwrap
>>> print(textwrap.fill(s, 70))
The Zen of Python, by Tim Peters Beautiful is better than
ugly.Explicit is better than implicit. Simple is better than complex.
Complex is better than complicated. Flat is better than nested. Sparse
is better than dense. Readability counts. Special cases aren't special
enough to break the rules. Although practicality beats purity. Errors
should never pass silently. Unless explicitly silenced. In the face of
ambiguity, refuse the temptation to guess. There should be one-- and
preferably only one --obvious way to do it. Although that way may not
be obvious at first unless you're Dutch. Now is better than never.
Although never is often better than *right* now. If the implementation
is hard to explain, it's a bad idea. If the implementation is easy to
explain, it may be a good idea. Namespaces are one honking great idea
-- let's do more of those!

>>> print(textwrap.fill(s, 40))
The Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit
is better than implicit. Simple is
better than complex. Complex is better
than complicated. Flat is better than
nested. Sparse is better than dense.
Readability counts. Special cases aren't
special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced. In the face
of ambiguity, refuse the temptation to
guess. There should be one-- and
preferably only one --obvious way to do
it. Although that way may not be obvious
at first unless you're Dutch. Now is
better than never. Although never is
often better than *right* now. If the
implementation is hard to explain, it's
a bad idea. If the implementation is
easy to explain, it may be a good idea.
Namespaces are one honking great idea --
let's do more of those!

>>> print(textwrap.fill(s, 40, initial_indent='    '))
    The Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit
is better than implicit. Simple is
better than complex. Complex is better
than complicated. Flat is better than
nested. Sparse is better than dense.
Readability counts. Special cases aren't
special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced. In the face
of ambiguity, refuse the temptation to
guess. There should be one-- and
preferably only one --obvious way to do
it. Although that way may not be obvious
at first unless you're Dutch. Now is
better than never. Although never is
often better than *right* now. If the
implementation is hard to explain, it's
a bad idea. If the implementation is
easy to explain, it may be a good idea.
Namespaces are one honking great idea --
let's do more of those!

>>> print(textwrap.fill(s, 40, subsequent_indent='    '))
The Zen of Python, by Tim Peters
    Beautiful is better than
    ugly.Explicit is better than
    implicit. Simple is better than
    complex. Complex is better than
    complicated. Flat is better than
    nested. Sparse is better than dense.
    Readability counts. Special cases
    aren't special enough to break the
    rules. Although practicality beats
    purity. Errors should never pass
    silently. Unless explicitly
    silenced. In the face of ambiguity,
    refuse the temptation to guess.
    There should be one-- and preferably
    only one --obvious way to do it.
    Although that way may not be obvious
    at first unless you're Dutch. Now is
    better than never. Although never is
    often better than *right* now. If
    the implementation is hard to
    explain, it's a bad idea. If the
    implementation is easy to explain,
    it may be a good idea. Namespaces
    are one honking great idea -- let's
    do more of those!
>>>

textwrap 模块中的 fill 方法用于对 text 中的单独段落自动换行,返回包含被换行段落的单独字符串。fill 函数属于快捷函数,若更复杂的情况,建议使用 TextWrapper 提高效率。可参阅 textwrap.TextWrapper 文档 获取更多的内容。

参考资料


来源
  1. David M. Beazley;Brian K. Jones.Python Cookbook, 3rd Edtioni.O’Reilly Media.2013.
  2. “6.1. string — Common string operations”.docs.python.org.Retrieved 7 January 2020
  3. '2. Built-in Functions".docs.python.org.Retrieved 6 January 2020
  4. “4. Built-in Types”.docs.python.org.Retrieved 3 January 2020
  5. “6.4. textwrap — Text wrapping and filling”.docs.python.org.Retrieved 9 January 2020

以上就是本篇的主要内容


欢迎关注『书所集录』公众号
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值