字符串
1. 字符串字面量
- 单引号:
'spa"m'
- 双引号:
"spa'm"
- 三引号:
'''...spam...'''
,"""...spam..."""
- 转义序列:
"s\tp\na\0m"
- 原始字符串:
r"C:\new\test.spm"
- 字节字面量:
b'spx01am'
- Unicode字面量:
u'eggs\u0020spam'
1.1 单引号和双引号字符串是相同的
在Python字符串中,单引号和双引号字符是可以互换的。字符串字面量包围在两个单引号和两个双引号中,将返回相同类型的对象。
>>> 'shrubbery', "shrubbery"
('shrubbery', 'shrubbery')
支持单引号和双引号字符串的原因是,可以不使用反斜杠转义就可以在一种引号的字符串中包含另一种引号:
>>> 'knight"s', "knight's"
('knight"s', "knight's")
尽量选择在字符串左右使用单引号包围,阅读起来稍稍简单。
Python会在表达式中自动拼接相邻的字符串字面量,当然也可以在两个字符串字面量之间使用加号(+)来拼接:
>>> "Meaning " 'of' " Life"
'Meaning of Life'
>>> "Meaning " + 'of' + " Life"
'Meaning of Life'
在字符串之间添加一个逗号会创建元组而不是字符串:
>>> 'knight\'s', "knight\"s"
("knight's", 'knight"s')
# 在单引号(或双引号)包围的字符串中如果要使用单引号(或双引号)需要使用反斜杠转义
1.2 转义序列代表特殊字符
反斜杠用来引入特殊的字符编码,称为转义序列。转义序列能够让我们再字符串中嵌入不容易通过键盘输入的字符。字符\
以及字符串字面量中在它后面的一个或多个字符,在生成的字符串对象中会被单个字符所替代,这个字符拥有通过转义序列定义的二进制值:
>>> s = 'a\nb\tc' # \n表示换行符,\t表示制表符
>>> print(s)
a
b c
>>> len(s) # 转义序列是单个字符
5
一些转义序列允许在字符串的字符之间嵌入绝对二进制数值:
>>> s = 'a\0b\0c'
>>> s
'a\x00b\x00c'
在Python中像\0
这样的空字符不会像C语言一样去结束一个字符。
不管如何指定不可打印的字符,在Python中都以十六进制显示:
>>> s = '\001\002\x03'
>>> s
'\x01\x02\x03'
如果Python认为\
后的字符不是有效的转义编码,那么它会直接在生成的字符串中保留反斜杠
然而不应该依赖此行为,如果希望使用反斜杠应当明确使用
\\
>>> x = "C:\py\code"
>>> x
'C:\\py\\code'
1.3 原始字符串阻止转义
引入转义字符后,需要特别注意含有反斜杠的字符串:
myfile = open('C:\new\text.dat', 'w')
这里明明想要打开C盘下new目录下的text.dat文件,然而由于这里含有反斜杠,并且反斜杠后的字符都是有效的转义编码(\n
, \t
),因此Python会认为这里想要打开一个名为C:(换行符)ew(制表符)ext.dat的文件。
如果字母r出现在字符串的第一个引号的前面,那么这一个字符串就是原始字符串(raw string),原始字符串将关闭转义机制。
原始字符串会将反斜杠当做字面量,原始字符串与输入的完全一致。
myfile = open(r'C:\new\text.dat', 'w')
myfile = open('C:\\new\\text.dat', 'w')
>>> x = "C:\new\text.dat"
>>> x
'C:\new\text.dat'
>>> path = r"C:\new\text.dat"
>>> path
'C:\\new\\text.dat'
>>> print(path)
C:\new\text.txt
>>> len(path)
15
注意:Python会自动在Windows和Unix的路径中使用斜杆
/
表示字符串路径:myfile = open('C:/new/text.tat') # 在windows中可以用左斜杆表示字符串路径
尽管原始字符串可以阻止转义,但原始字符串不能以单个反斜杠结尾,因为反斜杠会转义后面的引号字符,即r"...\"
不是一个有效的字符串字面量。如果想要使用单个反斜杠结束的原始字符串,可以使用如下方式:
>>> s1 = r'1\n\tc\\'
>>> s1
'1\\n\\tc\\\\'
>>> len(s1)
8
>>> s1[:-1]
'1\\n\\tc\\'
>>> s2 = r'1\n\tc' + '\\'
>>> s2
'1\\n\\tc\\'
1.4 三引号编写多行块字符串
Python中还有一种三引号的字符串字面量格式,有时候被称作块字符串。块字符串以三个引号(单引号或者双引号都可以)开始,并且紧跟任意行数的文本,并且以与开始时相同的三个引号结尾。
>>> mantra = """Always look
... on the bright
... side of life."""
>>>
>>> mantra
'Always look\n on the bright\nside of life.'
>>> print(mantra)
Always look
on the bright
side of life.
Python会把所有在三引号内的文本收集到一个单独的多行字符串中,并且在代码行转折处嵌入换行符(\n
),注意输入的是什么得到的块字符串就是什么,比如上面的字面量中,第二行开头有空格,第三行就没有。
块字符串会保留所有包围的文本,包括代码右侧的注释:
>>> menu = """spam # comments here added to string!
... eggs # ditto
... """
>>> menu
'spam # comments here added to string!\neggs # ditto\n'
三引号字符串在程序需要输入多行文本的时候很有用,比如在Python中嵌入HTML、XML或JSON代码。
三引号字符串也常用于文档字符串。
三行字符串也可用于废除大段的代码,这比每行之前加上#
号要容易得多。
2. 实际应用中的字符串
2.1 基础操作
>>> len('abc') # len函数将返回字符串的长度
3
>>> 'abc' + 'def' # +操作符,拼接两个字符串
'abcdef'
>>> 'Ni!' * 4 # *运算符,重复多个字符串
'Ni!Ni!Ni!Ni!'
len内置函数
返回字符串(或其他任何拥有长度的对象)的长度,使用+
相加两个字符串对象会创建一个新的字符串对象,其内容是两个字符串对象的内容相连,使用*
重复就像在字符串后再增加一定数量的自身。
注意:这里的
+
和*
运算符已经是重载过的,这里的+
和*
运算符的运算对象必须是字符串,不能混合字符串和数字,例如'abc' + 9将抛出异常。
可以使用for语句在循环中对字符串进行迭代,并使用in表达式运算符对字符和子字符串进行成员关系测试。
>>> for c in myjobs: print(c, end=' ')
...
h a c k e r
>>> "k" in myjobs
True
>>> "z" in myjobs
False
>>> 'hack' in 'hacker'
True
2.2 索引与分片
字符串中的字符可以通过索引来获取,python中的偏移量是从0开始的,以比字符串长度小1的偏移量结束。Python还支持使用负偏移量,从技术上说,一个负偏移量会与这个字符串的长度相加,从而得到一个正的偏移量,可以把负偏移量看作从结尾处反向计数。
>>> S = 'spam'
>>> S[0], S[-2]
('s', 'a')
分片是索引的一种扩张形式,返回的是一个完整片段而不是一个单独元素。
当使用一对以冒号分隔的偏移量(s[1:3])对字符串这样的序列对象进行分片时,Python将返回一个新的对象,其中包含了由这对索引所标识的连续的内容,左边的偏移量作为下边界(包含下边界在内),而右边的偏移量作为上边界(不包含上边界在内)。即Python将获取从下边界直到但不包括上边界的所有元素,并返回一个包含所有获取元素的新对象。如果左边界的偏移量省略的话,默认值为0,如果右边界的偏移量省略的话,默认值为字符串的长度。
分片(S[i:j])提取序列的连续部分:
S[1:3]表示提取出序列中从偏移量为1直到但是不包括偏移量为3之间的所有元素;
S[1:]得到除了第一个元素以外的全部元素(省略上边界的情况下,默认上边界的值为序列长度);
S[:-1]获取除最后一个元素以外的所有元素(省略下边界的情况下,下边界的值默认为0)。
S[:]获取从偏移量为0直到末尾的所有元素,实现了对S的顶层复制。
扩展分片
分片表达式可以增加一个可选的索引值作为步长,分片的完整形式变成了X[I:J:K]
,它表示“提取对象X中的所有对象,从偏移量I直到偏移量J-1,每隔K个元素索引一次”,其中步长K如果省略的话,默认值为+1。
例如X[1:10:2]会取出X中,偏移量为1至9之间,每隔一个元素的所有元素,即收集位于偏移量1、3、5、7、9出的元素。X[::2]由于上下边界值省略,默认值为0和序列的长度,因此会取出序列中从头到尾每隔一个元素的所有元素。
>>> S = 'abcdefghijklmnop'
>>> S[1:10:2]
'bdfhj'
>>> S[::2]
'acegikmo'
步长也可以使用负数来以相反的顺序(从右往左)来获取元素。
>>> S = 'hello'
>>> S[::-1] # S[::-1]可以将字符串反转
'olleh'
注意:使用负数步长时,前面两个边界的意义实际上进行了反转:
>>> S = 'abcdefg'
>>> S[5:1:-1]
'fedc'
# S[5:1:-1]表示从右往左来获取元素,左边界为偏移量5,右边界为偏移量1,实际上获取了偏移量为5、4、3、2的元素
分片实际上是使用一个分片对象进行索引:
>>> 'spam'[1:3]
'pa'
>>> 'spam'[slice(1, 3)]
'pa'
>>> 'spam'[::-1]
'maps'
>>> 'spam'[slice(None, None, -1)]
'maps'
2.3 字符串转换工具
在Python中不能够相加字符串和数字:
>>> '42' + 10
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str
int
函数可以将字符串转换为整数,float
函数可以将字符串转换为浮点数;
str函数
可以将数字转换为字符串,repr
函数也可以将数字转换为字符串,但repr函数返回可作为代码的字符串对象。
str函数和repr函数
str和repr函数都会把任意的对象转换为字符串表示,但是repr(默认的交互式命令中显示的就是repr)会产生看起来更像代码的结果,而str(print打印的就是str)转换为对用户更加友好的形式。对象同时拥有这两种方式,str用于一般用途,而repr带有额外细节。
>>> repr('spam') "'spam'" >>> str('spam') 'spam'
字符串代码转换
ord
函数可以将单个字符转换为其底层的ASCII码值,chr
函数则会将ASCII码转换为对应的字符。
>>> ord('S')
83
>>> chr(83)
'S'
>>> S = '5'
>>> chr(ord(S) + 1)
'6'
# 如下代码可以将二进制字符串转换为整数
>>> B = '1101'
>>> I = 0
>>> while B!= '':
... I = I * 2 + ord(B[0]) - ord('0')
... B = B[1:]
...
>>> I
13
# 当然也可以使用int函数将二进制字符串转换为整数
>>> int('1101', 2)
13
>>> bin(13)
'0b1101'
2.4 修改字符串
字符串是不可变序列,不能在字符串的原位置上修改:
>>> S = 'spam'
>>> S[0] = 'x'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
若要改变字符串,通常需要利用拼接、分片来建立并赋值一个新的字符串:
>>> S = 'x' + S[1:]
>>> S
'xpam'
>>> S = S + 'SPAM'
>>> S
'xpamSPAM'
注意,每修改一次字符串都会产生一个新的字符串对象,Python会自动对不再使用的字符串对象自动进行垃圾回收,所以新的字符串对象会重用之前的字符串对象所占的空间。
2.5 字符串方法
除了表达式运算符之外,Python字符串还提供了一系列更为复杂的文本处理任务的方法。在Python中,表达式和字符串可以在不同的类型直接工作,但是方法通常特定于对象类型才能使用。
方法调用语法
方法调用同时结合了一次属性获取和一次函数调用操作。
- 属性获取:
object.attribute
获取对象object中attribute属性的值 - 调用表达式:
function(arguments)
调用函数function的代码,向其传递零个或多个逗号分隔的参数argument对象,并且返回函数function执行的结果
方法调用语法:object.method(arguments)
Python首先读取对象object的方法method,然后调用它,传递对象object和参数arguments。
>>> S = 'spam'
>>> result = S.find('pa')
>>> result
1
字符串方法示例:修改字符串
替换子字符串
替换子字符串,可以通过分片和拼接来实现:
>>> S = 'spammy'
>>> S = S[:3] + 'xx' + S[5:]
>>> S
'spaxxy'
也可以通过replace
方法来替换子字符串:
>>> 'aa$bb$cc$dd'.replace('$', 'SPAM') # replace substr '$' with 'SPAM'
'aaSPAMbbSPAMccSPAMdd'
replace
方法的参数是最始的子串和用于替换最初的子串的新子串,replace
方法会对字符串进行全局搜索并替换。
注意:字符串方法每次都会返回一个新的字符串对象,因为字符串是不可变的,因此
replace
方法并没有真正在原处修改替换子字符串!
replace
默认会进行全局替换(即替换所有查找到的原子字符串为新的子字符串),也可以指定替换次数:
>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> S.replace('SPAM', 'EGGS') # 替换所有
'xxxxEGGSxxxxEGGSxxxx'
>>> S.replace('SPAM', 'EGGS', 1) # 替换一次
'xxxxEGGSxxxxSPAMxxxx'
查找子字符串
find
方法可以查找并返回字符串中某个子串出现处的偏移量,如果未找到该子串时则返回-1。子字符串查找就像是in表达式,只不过find方法会返回子串所在的位置。
>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> where = S.find('SPAM')
>>> where
4
rfind
方法作用相同,不过是从右到左查找子串。
index
方法类似find方法,但是在找不到子串时会抛出ValueError异常。
>>> S = 'xxxxSPAMxxxxSPAMxxxx'
>>> S.index('SPAM')
4
>>> S.index('egg')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: substring not found
rindex
方法作用相同,不过是从右到左查找子串。
字符串合并
字符串拼接和replace
方法每次调用都会生成新的字符串对象,虽然字符串是不可变的,但是如果想要对字符串进行原位置的修改,可以先将字符串转换成一个支持原位置修改的对象,之后再对转换后的对象进行合并:
>>> S = 'spammy'
>>> L = list(S)
>>> L
['s', 'p', 'a', 'm', 'm', 'y']
>>> L[3] = 'x'
>>> L[4] = 'x'
>>> L
['s', 'p', 'a', 'x', 'x', 'y']
>>> S = ''.join(L) # 以分隔符为空将列表L中的字符串连接在一起
>>> S
'spaxxy'
join
方法可以将列表(或其他可迭代对象)中的字符串连接在一起,并且在元素间用分隔符分隔开。
>>> 'SPAM'.join(['eggs', 'sausage', 'ham', 'toast'])
'eggsSPAMsausageSPAMhamSPAMtoast'
字符串分隔
字符串的split
方法可以将一个字符串按指定的分隔符分割成一系列子串并返回所生成的子串列表。
split
方法默认按空白符(空格、制表符、换行符)来进行分割。
>>> line = "aaa bbb ccc"
>>> cols = line.split()
>>> cols
['aaa', 'bbb', 'ccc']
split
可以指定具体的分隔符。
>>> line = 'bob,hacker,40'
>>> line.split(',')
['bob', 'hacker', '40']
>>> line = "i'mSPAMaSPAMlumberjack"
>>> line.split('SPAM') # 分割符也可以为多个字符
["i'm", 'a', 'lumberjack']
rsplit
方法作用相同,不过是从右到左分割字符串。
字符串的partition
方法和rpartition
方法同样可以分割字符串,不过partition
方法会在分隔符首次出现的位置拆分字符串,而rpartition
方法则会在分隔符最后一次出现的位置拆分字符串,两者都将返回一个 3 元组,其中包含分隔符之前的部分、分隔符本身,以及分隔符之后的部分。 如果分隔符未找到,则返回的 3 元组中包含两个空字符串以及字符串本身。
>>> line = 'bob,hacker,40'
>>> line.partition(',')
('bob', ',', 'hacker,40')
>>> line.rpartition(',')
('bob,hacker', ',', '40')
字符串大小写
capitalize
方法可以将字符串的首个字母转换为大写,其余为小写。
>>> line = "the knight who say Ni!"
>>> line.capitalize()
'The knight who say ni!'
swapcase
方法可以将字符串中的大写字母转换为小写,将小写字母转换为大写:
>>> line.swapcase()
'THE KNIGHT WHO SAY nI!'
title
方法返回字符串的标题版本,其中每个单词第一个字母为大写,其余字母为小写:
>>> line.title()
'The Knight Who Say Ni!'
upper
方法可以将字符串中的所有字母都转换为大写,lower
方法则可以将字符串中的所有字母都转换为小写:
>>> line.upper()
'THE KNIGHT WHO SAY NI!'
>>> line.lower()
'the knight who say ni!'
字符串去空
strip
方法可以去除字符串的前导和末尾的空白字符:
>>> ' spacious '.strip()
'spacious'
strip
方法也可以指定要移除的字符chars,此时strip
将会移除字符串的前导和末尾的所有chars字符,直至遇到第一个不包含在chars中的字符。
>>> 'www.example.com'.strip('cmowz.')
'example'
lstrip
和rstrip
方法的用法与strip
相同,不过lstrip
方法只移除前导空白符或指定字符,而rstrip
方法则只移除末尾的空白符或指定字符。
>>> ' spacious '.lstrip()
'spacious '
>>> >>> 'www.example.com'.lstrip('cmowz.')
'example.com'
>>> ' spacious '.rstrip()
' spacious'
>>> >>> 'www.example.com'.rstrip('cmowz.')
'www.example'
字符串字符判断
isalpha
方法:如果字符串中的所有字符都是字母或数字且至少有一个字符,则返回True
, 否则返回False
isascii
方法:如果字符串为空或字符串中的所有字符都是 ASCII ,返回True
,否则返回False
isdecimal
方法:如果字符串中的所有字符都是十进制字符且该字符串至少有一个字符,则返回True
,否则返回False
isdigit
方法:如果字符串中的所有字符都是数字,并且至少有一个字符,返回True
,否则返回False
isidentifier
方法:如果字符串是有效的标识符,返回True
,否则返回False
islower
方法:如果字符串中至少有一个区分大小写的字符,并且此类字符均为小写则返回True
,否则返回False
isnumeric
方法:如果字符串中至少有一个字符且所有字符均为数值字符则返回True
,否则返回False
isspace
方法:如果字符串中只有空白字符且至少有一个字符则返回True
,否则返回False
istitle
方法:如果字符串中至少有一个字符且为标题字符串则返回True
,否则返回False
issupper
方法:如果字符串中至少有一个区分大小写的字符且此类字符均为大写则返回True
,否则返回False
字符串前后缀
startswith
方法:如果字符串以指定的prefix开始则返回True
,否则返回False
endswith
方法:如果字符串以指定的prefix结尾则返回True
,否则返回False
>>> line = "the knight who say Ni!"
>>> line.startswith('the')
True
>>> line.endswith('Ni!')
True
2.6 字符串格式化表达式
如今的Python中的字符串格式化可以用两种形式实现:
- 字符串格式化表达式:
'...%s...' % (values)
- 字符串格式化方法调用:
'...{}...'.format(values)
格式化字符串表达式基础
格式化字符串:
1.在%运算符的左侧放置一个需要进行格式化的字符串,这个字符串带有一个或多个内嵌的转换目标,都以%开头(如%d);
2.在%运算符右侧放置一个(或多个,内嵌在元组中的)对象,这些对象将会插入到想让Python进行格式化的左侧的字符串中,并替换一个(或多个)转换目标;
>>> 'The knight who say %s!' % exclamation
'The knight who say Ni!'
>>> 'That is %d %s bird!' % (1, 'dead')
'That is 1 dead bird!'
注意:当只有一个替换标记时,则右侧的%运算符后直接跟想要替换的值即可;当有多个替换标记时,则需要在右侧%运算符后跟多个想要替换的值的元组。
高级格式化表达式语法
字符串格式化类型码:
字符串格式化类型码语法:%[(keyname)][flags][width][.precision]typecode
- (keyname):为索引在表达式右侧使用的字典提供键名称:
>>> '%(language)s has %(number)d quote types.' % {'language': 'Python', 'number': 2}
'Python has 2 quote types.'
- flags:特殊转换标识,主要有以下标识:
'0'
——转换将为数字值填充零字符;(需配合width使用)'-'
——转换值将靠左对齐;' '
(空格)——符号位转换产生的整数前将留出一个空格;'+'
——转换将为数字值添加正负号字符
>>> 'There is %03d birds' % 2
'There is 002 birds'
>>> 'There is %-3d birds' % 2
'There is 2 birds'
>>> 'There is % d birds' % 2
'There is 2 birds' # 2前多了一个空格
>>> 'There is %+d birds' % 2
'There is +2 birds'
- width:为被替换的文本给出总的最小字符宽度
>>> 'There is %3d birds' % 2
'There is 2 birds' # 2小于最小字符宽度3,不足的用空格补齐
>>> 'There is %3d birds' % 1000
'There is 1000 birds' # 1000大于最小字符宽度3,此时宽度不生效
- .precision:为浮点数字设置小数点后显示的位数(即精度)
>>> pi = 3.1415926
>>> 'pi approximatelly equals %.2f' % pi
'pi approximatelly equals 3.14'
>>> '%e | %E | %f | %g' % (x, x, x, x)
'1.234568e+00 | 1.234568E+00 | 1.234568 | 1.23457'
>>> '%-6.2f | %05.2f | %+06.1f' % (x, x, x)
'1.23 | 01.23 | +001.2'
2.7 字符串格式化方法调用
字符串格式化方法基础
字符串格式化方法是字符串方法,它使用主体字符串作为模板,并且接受任意多个参数,用来表示将要根据模板替换的值。
主体字符串中,花括号通过位置(如{1})、关键字(如{food})或者相对位置(如{})来制定替换及要插入的参数。
>>> template = '{0}, {1} and {2}'
>>> template.format('spam', 'ham', 'eggs')
'spam, ham and eggs'
>>> template = '{matto}, {pork} and {food}'
>>> template.format(matto='spam', pork='ham', food='eggs')
'spam, ham and eggs'
>>> template = '{matto}, {0} and {food}'
>>> template.format('ham', matto='spam', food='eggs')
'spam, ham and eggs'
>>> template = '{} , {} and {}'
>>> template.format('spam', 'ham', 'eggs')
'spam , ham and eggs'
>>> template = '%s , %s and %s'
>>> template % ('spam', 'ham', 'eggs')
'spam , ham and eggs'
>>> template = '%(matto)s, %(pork)s and %(food)s'
>>> template % dict({'matto': 'spam', 'pork': 'ham', 'food': 'eggs'})
'spam, ham and eggs'
添加键、属性和偏移量
像%格式化表达式一样,格式化字符串可以指定对象属性和字典键,方括号指定字典键,而点表示通过位置或关键字所引用的元素的对象属性
>>> import sys
>>> 'My {1[kind]} runs {0.platform}'.format(sys, {'kind': 'laptop'})
'My laptop runs win32'
>>> 'My {map[kind]} runs {sys.platform}'.format(sys=sys, map={'kind': 'laptop'})
'My laptop runs win32'
>>> data = dict(platform=sys.platform, kind='laptop')
>>> 'My {kind:<8} runs {platform:>8}'.format(**data)
'My laptop runs win32'
# **data把字典data解包为一组类似"name=value"的关键字参数
格式化字符串中的方括号可以指定列表的偏移量来执行索引,但是只有单个正偏移量才能在格式化字符串的语法中有效,提供想要指定负偏移量或者分片或使用任意表达式的结果,则必须在格式化字符串之外先运行表达式:
>>> somelist = list('SPAM')
>>> somelist
['S', 'P', 'A', 'M']
>>> 'first={0[0]}, third={0[2]}'.format(somelist)
'first=S, third=A'
>>> 'first={0[0]}, third={0[-1]}'.format(somelist) # 负索引将会出错
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not str
>>> 'first={0}, last={1}'.format(somelist[0], somelist[-1]) # format中指定具体的列表元素时才能使用负索引
'first=S, last=M'
>>> parts = somelist[0], somelist[-1], somelist[1:3]
>>> 'first={0}, last={1}, middle={2}'.format(*parts)
"first=S, last=M, middle=['P', 'A']"
# 这里使用*parts来解包一个元组的项作为单独的函数参数
高级格式化方法语法
对于格式化方法,可以在可能为空的替换目标的标识码之后使用一个冒号,后面跟着可以指定字段大小、对齐方式和特定类型编码的格式化说明符。
高级格式化方法语法:{fieldname component !conversionflag :formatspec}
- fieldname是标识替换目标的一个可选的数字或者关键字,可为空
- component是类似
'.attribute'
或'[index]'
的字符串,用来获取参数的属性或者索引值 - conversionflag如果出现则以!开始,后面跟着r、s或者a,在这个值上分别调用repr、str或者ascii内置函数
- formatspec如果出现则以:开始,后面格子文本,指定了如何表示该值,包括字段宽度、对齐方式、补零、小数精度等细节,以一个可选的数据类型码结束
formatspec书写格式:[[fill]align][sign][#][width][,][.precision][typecode]
- fill可以是除{或}以外的任意填充字符,align可以是<、>、=或^,分别表示左对齐、右对齐、符号字符后的填充、或者居中对齐
- sign可以是+、-或者空格
- width表示被替换文本的最小字符宽度
- ,(逗号)选项请求一个逗号表示千分位分隔符
- .precision表示浮点数的显示精度
- typecode则是数据类型码,与%格式化字符串表达式类似,如d表示整数、f表示浮点数、s表示字符串
>>> '{0:10} = {1:10}'.format('spam', 123.4567)
'spam = 123.4567'
>>> '{0:>10} = {1:<10}'.format('spam', 123.4567)
' spam = 123.4567 '
>>> import sys
>>> '{0.platform:>10} = {1[kind]:<10}'.format(sys, {'kind': 'laptop'})
' win32 = laptop '
也可以省略参数索引,不过会降低代码的可读性:
>>> '{:10} = {:10}'.format('spam', 123.4567)
'spam = 123.4567'
>>> '{:>10} = {:<10}'.format('spam', 123.4567)
' spam = 123.4567 '
>>> import sys
>>> '{.platform:>10} = {[kind]:<10}'.format(sys, {'kind': 'laptop'})
' win32 = laptop '
字符串格式化方法调用的浮点数格式化与字符串格式化表达式类似:
>>> '{0:e}, {1:.3e}, {2:g}'.format(3.14159, 3.14159, 3.14159)
'3.141590e+00, 3.142e+00, 3.14159'
>>> '{0:f}, {1:.2f}, {2:+06.2f}'.format(3.14159, 3.14159, 3.14159)
'3.141590, 3.14, +03.14'
字符串格式化方法也支持十六进制、八进制和二进制格式:
>>> '{0:x}, {1:o}, {2:b}'.format(255, 255, 255)
'ff, 377, 11111111'
>>> bin(255), int('11111111', 2), 0b11111111
('0b11111111', 255, 255)
>>> hex(255), int('ff', 16), 0xff
('0xff', 255, 255)
>>> oct(255), int('377', 8), 0O377
('0o377', 255, 255)
python还引入了一种新的内置format函数,可以用来格式化单独的一项:
>>> '{0:.2f}'.format(1.2345)
'1.23'
>>> '%.2f' % 1.2345
'1.23'
>>> format(1.2345, '.2f')
'1.23'
字符串格式化表达式 vs 字符串格式化方法
- 字符串格式化方法有一些额外的功能,而字符串格式化表达式不支持,如字符串格式化方法有二进制类型码和千分位分组:
>>> '{0:b}'.format(2 ** 16 - 1)
'1111111111111111'
>>> '%b' % (2 ** 16 - 1) # 格式化字符串表达式不支持二进制类型符
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unsupported format character 'b' (0x62) at index 1
>>> '{0:,d}'.format(999999999)
'999,999,999'
>>> '%,d' % 999999999 # 格式化字符串表达式不支持千分位分组
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unsupported format character ',' (0x2c) at index 1
2.8 通用类型分类
- 数字(整数、浮点数、小数、分数等):支持加法和乘法等;
- 序列(字符串、列表、元组):支持索引、分片和拼接等;
- 映射(字典):支持按键名称的索引等;
集合不属于以上任何一类,它是独立的分类
- 不可变类别(数字、字符串、元组、不可变集合frozenset)
不可变类型中的对象类型都不支持在原位置修改,但是可以通过运行表达式来创建新的对象然后将返回的结果分配给变量
- 可变类别(列表、字典、集合、字节数组)
可变类别可以不通过生成新的对象直接在原位置上进行修改
标签:字符,格式化,spam,Python,偏移量,字符串,方法 From: https://www.cnblogs.com/N1rv2na/p/18277690