前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 字符串的format用法

Python 字符串的format用法

作者头像
王云峰
发布2023-10-23 10:29:43
1800
发布2023-10-23 10:29:43
举报
文章被收录于专栏:Yunfeng's Simple Blog

更新 (2023-09-29)

利用f-string可以简化当前日期str的构造,不需要使用strftime等函数了:

代码语言:javascript
复制
from datetime import datetime

now = datetime.now()

str1 = f'{now:%y-%m-%d-%H:%M:%S}'
str2 = '{:%y-%m-%d-%H:%M:%S}'.format(now)
print(str1)
print(str2)

输出入下:

代码语言:javascript
复制
23-09-29-09:50:07
23-09-29-09:50:07

1. 引入

我有一个朋友,某天突然问我:你知道下面的Python语句什么含义,结果是多少吗?

代码语言:javascript
复制
'{:😄^+#20_x}'.format(12345)

我一看,十脸懵逼,吓得赶紧学了学Python的Format字符串的用法,总算明白了这个语句的含义。你想了解这个语句到底是什么鬼吗,欢迎跟我一起学。

2. 整体说明

Python的Format语法,可以用在两个场景:一个是{}.format中,另一个是f-string中,`f{xxx}’中,只不过后者支持外部定义的变量:

代码语言:javascript
复制
# .format way 1
print('Hello {}!'.format('World'))

# .format way 2
print('Hello {name}!'.format(name='World'))

# f-string
name = 'World'
print(f'Hello {name}!')

为了应对更复杂的使用场景,Python设计了一套全面的语法,来涵盖所有的使用情况。具体来说,这套语法将一个Format 语句分成五部分,分别是:

代码语言:javascript
复制
"{" [字段名称部分] ["!" 格式转换部分] [":" 格式规范部分] "}"

也就是左大括号和右大括号以及中间的核心三个部分, 其中方括号中的内容是可选的,也就是说最简单的format语法就是{}.format(‘xxx’),会打印format后的第一个内容。

下面分开看看核心的三个部分。

3. 字段名称部分

这一部分是用来定位要进行操作的变量。大括号中的编号对应这实际传入的参数,例如: 采用关键字形式:

代码语言:javascript
复制
'My name is {name}, I am {age} years old'.format(name='Root', age=100)
# My name is Root, I am 100 years old

这里的{name}对应format后面的关键字形式的参数name。

另一种是使用参数序号:

代码语言:javascript
复制
'My name is {0}, I am {1} years old'.format('Root', 100)
# My name is Root, I am 100 years old

这里的{0}对应Root, {1} 对应100,如果有更多的参数的话,编号按顺序往下继续。

注意这里的{idx}在字符串中可以出现任意次,且出现的顺序是任意的:

代码语言:javascript
复制
'{5} {5} {2}'.format('a','b','c','d','e', 'f')
# f f c

如果下标越界的话,会报错:

代码语言:javascript
复制
'{5} {5} {2}'.format('a','b','c')
IndexError: Replacement index 5 out of range for positional args tuple

另外一个特性是,可以忽略括号中的编号,这时候就按照从0开始的顺序来读取输入:

代码语言:javascript
复制
# 下面的命令等效于 'My name is {0}, I am {1} years old'.format('Root', 100)
'My name is {}, I am {} years old'.format('Root', 100)
# My name is Root, I am 100 years old

如果对复杂如列表或者字典,也可以使用下标或者属性来操作:

代码语言:javascript
复制
 # 列表例子
friends = ['foo', 'bar']
'{0[0]}'.format(friends)
# 'foo'

# 字典例子
info = {'name': 'Root', 'age': 100}
'{0[name]}'.format(info)
# 'Root'

# 属性对象例子
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age'])
p = Person('Root', 100)
'{0.name}'.format(p)
# 'Root
通过这些设置,能满足常见的需求。

4. 格式转换部分

这部分比较简单,在格式规范转换之前执行,通过感叹号加转换符号[r, s, a]之一,将原先的类型转换为字符串的类型,其中!a 表示对输入对象进行ascii()函数的调用,!s表示对输入对象进行str()函数的调用,而!r则调用repr()函数。

5. 格式规范部分

这部分是format格式中的大头,包含很多项设置,但都是可选的,例如上面的例子中我们都没有设置这部分。关于这部分的规范下面我们一一道来。

代码语言:javascript
复制
format_spec     ::=  [[fill]align][sign][#][0][width][grouping_option][.precision][type]
fill            ::=  <any character>
align           ::=  "<" | ">" | "=" | "^"
sign            ::=  "+" | "-" | " "
width           ::=  digit+
grouping_option ::=  "_" | ","
precision       ::=  digit+
type            ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

5.1 fill 和align: 填充和对齐部分

这部分包括填充和对齐,填充部分是任意的一个字符,如’+’, ‘*’, 或者😄。不设置的话,默认使用空格来填充。对齐方式包括下面四种:

“<”: 左对齐

代码语言:javascript
复制
# 以空格左对齐,长度为10位
>>> '{0:<10}'.format(3.14)
'3.14      '
# 以星号左对齐,长度为10位
>>> '{0:*<10}'.format(3.14)
'3.14******'

“>”:右对齐

代码语言:javascript
复制
# 以空格右对齐,长度为10位
>>> '{0:>10}'.format(3.14)
'      3.14'

“=”:只对数值类型使用,表示对齐强制放到正负号和数值之间

代码语言:javascript
复制
# 以星号数值对齐,长度为10位
>>> '{0:*=10}'.format(-3.14)
'-*****3.14'

“^”: 居中对齐

代码语言:javascript
复制
>>> '{0:*^10}'.format(-3.14)
'**-3.14***'

5.2 sign: 符号部分

这部分有三个选项;

代码语言:javascript
复制
+ "+": 正负号都加符号
>>> '{0:+} {1:+}'.format(3.14, -3.14)
'+3.14 -3.14'

“-“: 只有负数前面才加符号

代码语言:javascript
复制
>>> '{0:-} {1:-}'.format(3.14, -3.14)
'3.14 -3.14'

“ “: 正数前面加空格,负数前面加负号

代码语言:javascript
复制
>>> '{0: } {1: }'.format(3.14, -3.14)
' 3.14 -3.14'

5.3 #: 进制表示位

使用#号结合不同的进制表示符号(下面详细展开),会在进制前面增加对应的负号,如二进制前增加0b, 八进制前增加0o, 十六进制前增加0x

代码语言:javascript
复制
# 二进制
>>> '{0:#b}'.format(233)
'0b11101001'
# 八进制
>>> '{0:#o}'.format(233)
'0o351'
# 十进制
>>> '{0:#d}'.format(233)
'233'
# 十六进制
>>> '{0:#x}'.format(233)
'0xe9

5.4 width: 显示的字符长度

这一部分表示显示多少位字符,包括pad的字符位。

代码语言:javascript
复制
# 总长度为10位,不足的部分用默认的符号补齐
>>> '{0:10}'.format(233)
'       233'

5.5 grouping_option: 千位的标识符号

这部分表示千位的标识符号,有,\_两种选择:

代码语言:javascript
复制
>>> '{0:10,}'.format(23333333)
'23,333,333'
>>> '{0:10_}'.format(23333333)
'23_333_333'

5.6 .precision: 数值精度

这个表示浮点数的精度位数:

代码语言:javascript
复制
>>> '{0:.3}'.format(3.14159)
'3.14'

5.7 type: 格式类型

这部分表示最终的展示类型,共有下面这些类:

代码语言:javascript
复制
"b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

每种的解释如下:

“b”: 二进制表示

代码语言:javascript
复制
>>> "{0:b}".format(8)
'1000

“c”: 只支持整数,将其转换为对应的unicode符号

代码语言:javascript
复制
>>> "{0:c}".format(23)
'\x17'

“d”: 十进制表示

代码语言:javascript
复制
>>> "{0:d}".format(8)
'8'

“e”: 科学计数法,采用小写的e

代码语言:javascript
复制
>>> "{0:e}".format(8)
'8.000000e+00'

“E”: 科学计数法,采用大写的E

代码语言:javascript
复制
>>> "{0:E}".format(8)
'8.000000E+00

“f”: 浮点数表示

代码语言:javascript
复制
>>> "{0:f}".format(8)
'8.000000'

“F”: 与”f”基本相同,除了将nan显示为NAN, inf显示为INF

代码语言:javascript
复制
>>> "{0:F}".format(8)
'8.000000'

“g”: 通用数据格式

代码语言:javascript
复制
>>> "{0:g}".format(8)
'8'

“G”: 通用数据格式

代码语言:javascript
复制
>>> "{0:G}".format(8)
'8'

“n”: 数值格式

代码语言:javascript
复制
>>> "{0:n}".format(8)
'8'

“o”: 八进制格式

代码语言:javascript
复制
>>> "{0:o}".format(8)
'10

“s”: 只能对字符串使用,字符串类型,默认输出类型,可以忽略

代码语言:javascript
复制
>>> "{0:s}".format('www')
'www'
>>> "{0}".format('www')
'www'

“x”: 十六进制

代码语言:javascript
复制
>>> "{0:#x}".format(8)
'0x8'

“X”: 十六进制,符号标识采用大写的X

代码语言:javascript
复制
>>> "{0:#X}".format(8)
'0X8'

“%”: 只对数值类型使用,以百分比的形式显示

代码语言:javascript
复制
>>> "{0:%}".format(8)
'800.000000%'
>>> "{0:%}".format(0.001)
'0.100000%'

6. 解答开头的神秘符号串

有了上面的知识,我们就可以解开文章开头的的神秘符号串了:

  1. 以笑脸符号作为pad的字符,且居中对齐,总长为20个符号
  2. 在正数前面增加加号
  3. 显示为16进制,并且显示前面的进制标注符号 结果如下:
代码语言:javascript
复制
>>>'{:😄^+#20_x}'.format(12345)
'😄😄😄😄😄😄+0x3039😄😄😄😄😄😄😄'

6. 参考

  1. https://docs.python.org/3/library/string.html
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-282,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 更新 (2023-09-29)
  • 1. 引入
  • 2. 整体说明
  • 3. 字段名称部分
  • 4. 格式转换部分
  • 5. 格式规范部分
    • 5.1 fill 和align: 填充和对齐部分
      • 5.2 sign: 符号部分
        • 5.3 #: 进制表示位
          • 5.4 width: 显示的字符长度
            • 5.5 grouping_option: 千位的标识符号
              • 5.6 .precision: 数值精度
                • 5.7 type: 格式类型
                • 6. 解答开头的神秘符号串
                • 6. 参考
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档