在本章中将学习字符串的格式化与常用方法。Python中字符串格式化的功能尤为强大,可以说是随心所欲,让你的字符串呈现各种形式。而字符串中的方法可以辅助我们对字符串进行各种常用的操作,如搜索字符串、连接字符串、对字符串中的字母进行大小写转换、替换字符串、截取字符串等。
字符串的一类重要操作就是格式化,例如,将整数转换为字符串时,要求不满8位的,前面补0,这就是字符串格式化的一个标准案例。本节将详细讲解Python中有哪些格式化字符串的方法。
微课视频
字符串格式化相当于字符串模板。也就是说,如果一个字符串有一部分是固定的,而另一部分是动态变化的,那么就可以将固定的部分做成模板,然后那些动态变化的部分使用字符串格式化操作符(%)
替换。如一句问候语:"Hello李宁",其中"Hello"是固定的,但"李宁"可能变成任何一个人的名字,如"乔布斯",所以在这个字符串中,"Hello"是固定的部分,而"李宁"是动态变化的部分,因此,需要用"%"操作符替换"李宁",这样就形成了一个模板。
Hello %s
上面的代码中,"%"后面的s是什么呢?其实字符串格式化操作符后面需要跟着动态值的数据类型,以及更复杂的格式(如对于浮点数来说,小数点后要保留几位),这里的"%s"表示动态部分要被替换成字符串类型的值。如果在字符串模板中有多个要被替换的部分,需要按顺序用"%"表示,然后在格式化字符串时,传入的值也要符合这个顺序。
下面的例子首先定义了一个字符串模板,然后传入了两个字符串类型的值来格式化字符串,最后将格式化后的字符串输出。
代码位置:src/string/basic_format1.py
# 定义字符串模板 formatStr = "Hello %s. Today is %s, Are there any activities today?" # 初始化字符串格式化参数值,此处必须使用元组,不能使用列表 values = ('Mike', 'Wednesday') # 格式化字符串 print(formatStr % values)
程序运行结果如图5-1所示。
图5-1 格式化字符串
从上面的代码可以看出,不仅在为字符串模板指定格式化参数时要使用百分号(%),在格式化字符串时,也要使用"%"操作符。还有就是指定字符串格式化参数值要使用元组,在这里不能使用列表。
在前面的例子中,只是使用了字符串作为格式化参数,但在实际的应用中,可能会有其他类型的字符串格式化参数。如果遇到这种情况,可以使用str函数将这些数据类型的值转换为字符串类型的值,然后再传入字符串模板,这么做在大多数情况下是可行的,但如果要对格式化参数值有更进一步的要求,仅使用str函数就做不到了,这就要使用能表示这些数据类型的格式化参数,如"%f"表示浮点类型的格式化参数。
代码位置:src/string/basic_format2.py
# 在这个字符串模板中,包含了浮点数和整数类型的格式化参数 formatStr1 = "PI是圆周率,它的值是%.4f(保留小数点后%d位)" # 导入math模块中的pi变量 from math import pi # 定义与formatStr1对应的格式化参数值 values1 = (pi, 4) # 字符串格式化,运行结果:PI是圆周率,它的值是3.1416(保留小数点后4位) print(formatStr1 % values1) # 在这个字符串模板中,包含了整数和字符串类型的格式化参数 formatStr2 = "这件事的成功率是%d%%, 如果有%s参与,成功率会提升至%d%%" values2 = (56, "John",70) # 运行结果:这件事的成功率是56%, 如果有John参与,成功率会提升至70% print(formatStr2 % values2) values3 = (66,"Mike") # 由于指定的参数值的数量和格式化参数的数量不匹配,所以会抛出异常 print(formatStr2 % values3)
程序的运行结果如图5-2所示。
图5-2 不同数据类型的格式化参数
在上面的代码中,为字符串格式化指定了不同数据类型的格式化参数。如果要在格式化字符串中显示百分号(%),就要使用两个百分号(%%)表示。当传入的参数值的数量与格式化参数的数量不匹配时,就会抛出异常。
微课视频
在string模块中提供了一个用于格式化字符串的Template类,该类的功能是用同一个值替换所有相同的格式化参数。Template类的格式化参数用美元符号($)开头,后面跟着格式化参数名称,相当于变量名。在格式化时,需要使用Template类的substitute方法,该方法用于指定格式化参数对应的值。
在上面的代码中,通过Template类的构造方法传入了一个格式化字符串,在这个格式化字符串中包含了3个"$s",然后调用了substitute方法格式化这个字符串,该方法指定了s参数值为"Hello",最后的替换结果是"Hello Hello Hello",也就是说,在格式化字符串中,有多少个"$s",就替换多少个"$s"。substitute方法还可以通过字典(见第6章)设置格式化参数的值。
下面的例子使用Template格式化字符串,当格式化参数是一个字符串的一部分时,需要用一对大括号({})将格式化参数变量括起来。
代码位置:src/string/template_string.py
# 引用string模块中的Template类 from string import Template template1 = Template("$s是我最喜欢的编程语言, $s非常容易学习,而且功能强大") # 指定格式化参数s的值是Python # 运行结果:Python是我最喜欢的编程语言, Python非常容易学习,而且功能强大 print(template1.substitute(s='Python')) # 当格式化参数是一个字符串的一部分时,为了和字符串的其他部分区分开, # 需要用一对大括号将格式化参数变量括起来 template2 = Template("${s}stitute") # 运行结果:substitute print(template2.substitute(s='sub')) template3 = Template("$dollar$$相当于多少$pounds") # 运行结果:20$相当于多少英镑 print(template3.substitute(dollar=20,pounds='英镑')) template4 = Template("$dollar$$相当于多少$pounds") data = {} data['dollar'] = 100 data['pounds'] = '英镑' # 运行结果:100$相当于多少英镑 print(template4.substitute(data))
微课视频
字符串本身也有一个format方法用于格式化当前的字符串。这个format方法和前面讲的格式化操作符(%)不太一样。字符串格式化参数并不是用百分号(%)表示,而是用一对大括号({}),而且支持按顺序指定格式化参数值和关键字格式化参数。例如,下面的代码通过format方法按顺序为格式化字符串指定了参数值。
可以看到,上面的代码在字符串中指定了3对空的大括号,这代表3个格式化参数,不需要指定数据类型,可以向其传递Python语言支持的任何值。通过format方法传入3个值(1,2,3),这3个值会按顺序替换格式化字符串中的3对空的大括号。
命名格式化参数是指在一对大括号中指定一个名称,然后调用format方法时也要指定这个名称。
上面的代码在3对大括号中分别添加了"a""b""c"。通过format方法指定了这3个命名参数的值。可以看到,并没有按顺序指定命名参数的值。这也是使用命名参数的好处,只要名字正确,format参数的顺序可以任意指定。当然,顺序方式和命名参数方式可以混合使用,而且还可以指定顺序方式中格式化参数从format方法提取参数值的顺序,甚至可以提取format方法参数值的一部分。接连抛出了这么多功能,可能很多读者有点应接不暇了,下面的例子演示了format的一些核心用法。
代码位置:src/string/format_method.py
# 包含了两个空的大括号,format方法需要按顺序指定格式化参数值 s1 = "Today is {}, the temperature is {} degrees." # format方法的第1个参数值对应s1的第1对大括号,第2个参数值对应s1的第2对大括号 # 运行结果:Today is Saturday, the temperature is 24 degrees. print(s1.format("Saturday", 24)) # 包含了两个命名格式化参数:一个是{week},另一个是{degree} s2 = "Today is {week}, the temperature is {degree} degrees. " # format方法的第1个参数指定了{degree}的值,第2个参数指定了{week}的值, # 可以将degree和week调换,s2.format(week ="Sunday", degree = 22) # 运行结果:Today is Sunday, the temperature is 22 degrees. print(s2.format(degree = 22, week ="Sunday")) # 混合了顺序格式化参数和关键字格式化参数的两种方式 s3 = "Today is {week}, {},the {} temperature is {degree} degrees. " # format方法的参数,前面应该是按顺序传递的格式化参数值,后面是关键字格式化参数值,顺序不能调换 # 这样做是错误的:s3.format(degree = 22, "aaaaa", 12345, week ="Sunday") # 运行结果:Today is Sunday, aaaaa,the 12345 temperature is 22 degrees. print(s3.format("aaaaa", 12345, degree = 22, week ="Sunday")) # 为顺序格式化参数指定了从format方法获取参数值的顺序,{1}表示从format方法的第2个参数取值 # {0}表示从format方法的第1个参数取值 s4 = "Today is {week}, {1},the {0} temperature is {degree} degrees. " # 运行结果:Today is Sunday, 12345,the aaaaa temperature is 22 degrees. print(s4.format("aaaaa", 12345, degree = 22, week ="Sunday")) # 定义了一个列表 fullname = ["Bill", "Gates"] # {name[1]}取fullname列表中的第2个值(Gates) # format方法通过命名参数,为name名字指定了fullname列表。运行结果:Mr Gates print("Mr {name[1]} ".format(name = fullname)) # 导入math模块 import math # 访问math模块中的“__name__”变量来获取模块的名字,访问math模块中的pi变量获取PI的值 s5 = "The {mod.__name__} module defines the value {mod.pi} for PI" # format方法为mod命名参数指定了math模块 # 运行结果:The math module defines the value 3.141592653589793 for PI print(s5.format(mod = math))
微课视频
format方法的功能远不止这些,在一对大括号中添加一些字符串格式化类型符,可以对格式化字符串进行更多的控制。例如,下面的代码会将一个字符串类型的格式化参数值按原样输出、通过repr函数输出,以及输出其Unicode编码。
print("{first!s} {first!r} {first!a}".format(first = "中"))
执行这行代码,会输出如下的结果。
中 '中' '\u4e2d'
除此之外,format方法还支持很多其他的控制符,例如,可以将整数按浮点数输出,也可以将十进制数按二进制、八进制、十六进制格式输出。
下面的例子使用了s、r、a、f、b、o、x和%字符串格式化类型符对字符串进行格式化。
代码位置:src/string/format_args.py
# 运行结果:原样输出:中 调用repr函数:'中' 输出Unicode编码:'\u4e2d' print("原样输出:{first!s} 调用repr函数:{first!r} 输出Unicode编码:{first!a}".format (first = "中")) # 将21按浮点数输出,运行结果:整数:21 浮点数:21.000000 print("整数:{num} 浮点数:{num:f}".format(num = 21)) # 将56按十进制、二进制、八进制和十六进制格式输出 # 运行结果:十进制:56 二进制:111000 八进制:70 十六进制:38 print("十进制:{num} 二进制:{num:b} 八进制:{num:o} 十六进制:{num:x}".format(num = 56)) # 将533按科学记数法格式输出,运行结果:科学记数法:5.330000e+02 print("科学记数法:{num:e}".format(num = 533)) # 将0.56按百分比格式输出,运行结果:百分比:56.000000% print("百分比:{num:%} ".format(num = 0.56))
表5-1是format支持的一些常用的字符串格式化类型符。
表5-1 常用的字符串格式化类型符
在表5-1中提到的inf和nan是Python中的特殊值。inf表示无穷大。float("inf")表示正无穷,float("-inf")表示负无穷(无穷小)。NaN可解释为非数字,NaN既不是无穷大,也不是无穷小,而是无法在计算时返回的一个符号。例如,执行下面的代码会格式化inf和NaN。
# 运行结果:NAN inf print("{:F} {:f}".format(float("nan"),float("inf")))
注意,在使用表5-1中的字符串格式化类型符时需要在前面加上冒号(:)或感叹号(!),大多数类型符加冒号,有一部分(如a、r)要加感叹号。如{!r}、{!a},如果写成{r}、{a}会抛出异常。
微课视频
使用类型符f格式化浮点数时,默认在小数点后会保留6位数。其实,使用format方法也可以让该格式化数值的整数部分占用一个固定的位数,也可以看作控制字段的宽度。例如,使用{num:10}格式化一个数值,可以让该数值靠右对齐,如果数值的长度(整数部分+小数点+小数部分的长度)不足10位,那么左边会保留空格。当然,如果数值的长度超过了10位,就会按原样显示。
format方法同样也可以控制一个浮点数显示的小数位数,也就是数值的精度。例如,使用{pi:.2f}可以让pi指定的浮点数保留2位小数,这种格式与格式化运算符(%)类似。
还可以使用{num:10.2f}让num指定的数值既保留2位小数,又可以右对齐,不足10位左侧补空格。
本节涉及最后一个问题就是千分位分隔符(,),对于一个特别长的数值,如果不使用千分位分隔符对数值进行分隔,那么就需要一位一位地数了。如果使用{:,}格式化一个数值,那么format方法就会为该数值的整数部分加上千分位分隔符。
下面的例子通过format方法将数值的宽度设为12,将字符串的宽度设为10,这样数值和字符串前面都会补空格了(如果长度不足的话)。然后让圆周率PI保留小数点后2位,并且设置PI显示的宽度为10。再将精度设置应用于字符串中,相当于截取字符串前面n个字符。最后,用千分位分隔符显示一个非常大的整数googol。这是Google的由来,表示10的100次幂。
代码位置:src/string/format_features1.py
# 设置52的显示宽度为12,也就是说,52的左侧会有10个空格 print("{num:12}".format(num = 52)) # 将“Bill”的显示宽度设为10,对于字符串来说,是右侧补空格,也就是说,“Bill”右侧会显示6个字符 print("{name:10}Gates".format(name="Bill")) # 从math模块导入了pi from math import pi # 让圆周率PI保留2位小数 print("float number:{pi:.2f}".format(pi=pi)) # 让圆周率PI保留2位小数的同时,整个宽度设为10,如果不足10位,会左侧补空格 print("float number:{pi:10.2f}".format(pi=pi)) # 将精度应用于字符串,{:.5}表示截取“Hello World”的前5个字符,运行结果:Hello print("{:.5}".format("Hello World")) # 用千分位分隔符输出googol print("One googol is {:,}".format(10 ** 100))
程序运行结果如图5-3所示。
图5-3 字段宽度、精度和千分位分隔符
在5.1.5节讲到使用format方法可以让该格式化的值左侧或右侧补空格,不过这种补空格的效果看上去并不美观,而且一般的用户也分不清前面或后面到底有多少个空格。所以最合适的方式就是在值的前面或后面补0。例如,如果写一本书,章节超过了10章,为了让每一章的序号长度都一样,可以使用01、02、03、……、11、12这样的格式。对于10以后的章节,按原样输出即可。不过对于10以下的章节,就需要在数字前面补一个0了。要实现这个功能,就需要使用{chapter:02.0f}格式化章节序号。其中chapter是格式化参数,第一个0表示如果位数不足时前面要补0;2表示整数部分是2位数字;第2个0表示小数部分被忽略;f表示以浮点数形式格式化chapter指定的值。
# 运行结果:第04章 print("第{chapter:02.0f}章".format(chapter = 4));
如果想用format方法控制值的左、中、右对齐,可以分别使用"<""^"">"。
# 让1、2、3分别以左、中和右对齐方式显示 print('{:<10.2f}\n{:^10.2f}\n{:>10.2f}'.format(1,2,3))
不管是哪种方式对齐(左、中、右),在很多情况下,值的总长度要比指定宽度小,在默认情况下,不足的位要补空格,但也可以通过在"<""^"">"前面加符号,让这些不足的位用这些符号替代空格补齐。
# “#”号在宽度为20的区域内中心对齐,并左、右两侧添加若干井号(#),两侧各添加8个井号 # 运行结果:######## 井号 ######## print("{:#^20}".format(" 井号 "))
对于需要在前面显示负号的数值,如-3、-5。可以通过在等号(=)前面加上字符,以便在负号和数值之间加上特殊符号。
# 在5.43和负号(-)之间显示“^”,运行结果:-^^^^^5.43 print("{0:^=10.2f}".format(-5.43))
最后讨论一下进制转换。如果将十进制数分别转换为二进制、八进制和十六进制数,需要分别使用"b"、"o"和"x"类型符。如下面的代码将43转换为二进制数。
在Python中有一种f字符串,也就是在字符串之前加一个f,这样在字符串中就可以直接使用外部变量了,只不过变量要使用一对大括号括起来。
name = 'Bill' age = 30 # 运行结果:姓名:Bill, 年龄:30 print(f'姓名:{name}, 年龄:{age}')
本节会详细介绍字符串中的核心方法,通过这些方法,可以完成字符串的大多数操作。
微课视频
center方法用于将一个字符串在一定宽度的区域居中显示,并在字符串的两侧填充指定的字符(只能是长度为1的字符串),默认填充空格。
可能很多读者看到对center方法的描述,一下子就想起来前面讲的format方法和居中符号(^),其实完全可以用format方法代替center方法实现同样的效果,只是使用center方法更简单,更直接一些。
center方法有两个参数:第1个参数是一个数值类型,指定字符串要显示的宽度;第2个参数是可选的,需要指定一个长度为1的字符串,如果指定了第2个参数,那么center方法会根据第1个参数指定的宽度让字符串居中显示,字符串的两侧填充第2个参数指定的字符,如果不指定第2个参数,那么就用空格填充字符串的两侧区域。
下面的例子同时使用center方法和format方法让一个字符串在一定宽度的区域居中显示,并且在字符串两侧的区域填充指定的字符。
代码位置:src/string/center.py
# 使用center方法让“hello”在宽度为30的区域居中显示,两侧区域填充空格 print("<" + "hello".center(30) + ">") # 使用format方法让“hello”在宽度为30的区域居中显示,两侧区域填充空格 print("<{:^30}>".format("hello")) # 使用center方法让“hello”在宽度为30的区域居中显示,两侧区域填充星号(*) print("<" + "hello".center(30,"*") + ">") # 使用format方法让“hello”在宽度为30的区域居中显示,两侧区域填充星号(*) print("<{:*^30}>".format("hello"))
程序运行结果如图5-4所示。
图5-4 使用center方法和format方法让字符串居中显示
find方法用于在一个大字符串中查找子字符串,如果找到,find方法返回子字符串的第1个字符在大字符串中出现的位置,如果未找到,find方法返回-1。
s = "hello world" # 在s中查找“world”,运行结果:6 print(s.find("world")) # 在s中查找“ok”,未找到,运行结果:-1 print(s.find("ok"))
find方法还可以通过第2个参数指定开始查找的位置。
s = "hello world" # 从开始的位置查找“o”,运行结果:4 print(s.find("o")) # 从位置5开始查找“o”,运行结果:7 print(s.find("o",5))
find方法不仅可以通过第2个参数指定开始查找的位置,还可以通过第3个参数指定结束查找的位置。
s = "hello world" # 从第5个位置开始查找,到第8个位置查找结束,运行结果:-1 print(s.find("l",5,9)) # 从第5个位置开始查找,到第9个位置查找结束,运行结果:9 print(s.find("l",5,10))
要注意的是,find方法的第3个参数指定的位置是查找结束位置的下一个字符的索引。所以s.find("l",5,9)会搜索到s中索引为8的字符为止。
微课视频
join方法用于连接列表中的元素,是split方法(在5.2.4节介绍)的逆方法。
list = ['1','2','3','4','5'] s = "*" # 将字符串s与list中的每个元素值分别进行连接,然后再把连接的结果进行合并 # 运行结果:1*2*3*4*5 print(s.join(list))
可以看到,join方法会将s放到list列表元素的后面,从而得到了"1*2*3*4*5"。那么可能有的读者会问,这个join方法有什么用呢?其实join方法的一个典型的应用就是组合出不同平台的路径。例如,Linux/UNIX平台的路径分隔符是斜杠(/),而Windows平台的路径分隔符是反斜杠(\),而且前面还有盘符。使用join方法可以很轻松地生成不同平台的路径。
下面的例子演示了如何使用join方法连接字符串和序列元素,并通过join方法生成Linux和Windows平台的路径。
代码位置:src/string/join.py
list = ['a','b','c','d','e'] s = "+" # 连接s和list,运行结果:a+b+c+d+e print(s.join(list)) # 用逗号(,)运算符指定路径的每部分 dirs = '','usr','local','nginx','' # 使用join方法生成Linux格式的路径 linuxPath = '/'.join(dirs) # 运行结果:/usr/local/nginx/ print(linuxPath) # 使用join方法生成Windows格式的路径 windowPath = 'C:' + '\\'.join(dirs) # 运行结果:C:\usr\local\nginx\ print(windowPath) numList = [1,2,3,4,5] # 抛出异常 print(s.join(numList))
程序运行结果如图5-5所示。
图5-5 使用join方法连接字符串和序列元素
从上面的代码可以看到,与字符串连接的序列元素必须是字符串类型,如果是其他数据类型,如数值,在调用join方法时会抛出异常。
微课视频
split方法和join方法互为逆方法。split方法通过分隔符将一个字符串拆成一个序列。如果split方法不指定任何参数,那么split方法会把所有空格(空格符、制表符、换行符等)作为分隔符。
下面的例子使用split方法将一个加法表达式的操作数放到了一个序列中,并输出该序列。并且将一个Linux格式的路径中的每个组成部分放到了一个序列中,并利用这个列表和join方法,将路径转换为Windows的格式。最后将一条英文句子利用空格分隔符将每个单词放到了一个序列中,并输出该序列。
代码位置:src/string/split.py
# 将表达式的操作数放到了序列中,并输出该序列 # 运行结果:['1', '2', '3', '4', '5'] print("1+2+3+4+5".split("+")) # 将Linux格式的路径的每个组成部分放到一个序列中 list = '/usr/local/nginx'.split('/') # 运行结果:['', 'usr', 'local', 'nginx'] print(list) # 利用join方法重新生成了Windows格式的路径 # 运行结果:C:\usr\local\nginx print("C:" + "\\".join(list)) # 将英文句子中的单词放到序列中,然后输出 # 运行结果:['I', 'like', 'python'] print("I like python".split())
微课视频
lower方法和upper方法分别用于将字符串中的所有字母字符转换为小写和大写。而capwords函数并不是字符串本身的方法,而是string模块中的函数,之所以在这里介绍,是因为该函数与lower方法和upper方法有一点关系,就是capwords函数会将一个字符串中独立的英文单词的首字母都转换为大写,例如,"that's all"如果用capwords函数转换,就会变成"That's All"。
下面的例子使用lower方法和upper方法将字符串中的字母字符大小写互转,并在序列中查找指定字符串时,首先将列表中的元素都转换为小写,然后进行比较。最后使用capwords函数将一个字符串中的所有独立的英文单词的首字母都转换为大写。
代码位置:src/string/lower_upper_capwords.py
如果无法保证字符串在序列、数据库中保存的是大写还是小写形式,那么在查找字符串时,应该先将数据源中的字符串转换为小写或大写形式,然后再进行比较。
replace方法用于将一个字符串中的子字符串替换成另外一个子字符串。该方法返回被替换后的字符串,如果在原字符串中未找到要替换的子字符串,那么replace方法就返回原字符串。其实replace方法就是一个查找替换的过程。
# 运行结果:This is a bike print("This is a car".replace("car", "bike")) # 运行结果:This is a car print("This is a car".replace("place", "bike"))
微课视频
strip方法用于截取字符串的前后空格,以及截取字符串前后指定的字符。
下面的例子演示了如何使用strip方法截取字符串前后空格,以及如何截取字符串前后指定的字符。
代码位置:src/string/strip.py
使用strip方法应了解如下几点:
(1)strip方法与lower方法一样,在比较字符串时,最好利用lower方法将两个要比较的字符串都变成小写,以及都截取前后的空格。因为无法保证数据源是否满足要求,所以要尽可能通过代码来保证规范一致。
(2)strip方法只会截取字符串前后的空格,不会截取字符串中间的空格。
(3)如果指定strip方法的参数(一个字符串类型的值),strip方法会将字符串参数值中的每个字符当作要截取的目标。只要在字符串前后出现了其中一个字符,将会被截取。在本例中指定的参数值是"*&",因此,只要在字符串前后有空格,'*'和'&'就会被截取。但字符串中间的这些字符不会被截取。
微课视频
translate方法与replace方法类似,都用来替换字符串中的某一部分,只是translate方法只用来替换单个字符,而replace方法可以用来替换一个子字符串。不过从效率上来说,translate方法要更快一些。
在使用translate方法之前,需要先使用maketrans方法创建一张替换表,该方法属于字符串本身。
# 创建一张替换表,表示要将'a'和'k'分别替换成'*'和'$' table = s.maketrans("ak", "*$")
然后调用字符串的translate方法根据table替换相应的字符。
下面的例子首先使用maketrans方法创建一张替换表,然后使用translate方法替换字符串中相应的字符,并且删除相应的字符。
代码位置:src/string/translate.py
s = "I not only like python, but also like kotlin." # 创建一张替换表 table = s.maketrans("ak", "*$") # 在控制台输出替换表,运行结果:{97: 42, 107: 36} print(table) # 在控制台输出替换表的长度,运行结果:2 print(len(table)) # 根据替换表替换s中相应的字符,运行结果:I not only li$e python, but *lso li$e $otlin. print(s.translate(table)) # 创建另外一张替换表,在这里指定了maketrans方法的第3个参数,该参数用于指定要删除的字符 table1 = s.maketrans("ak", "$%", " ") # 根据替换表替换s中相应的字符,并删除所有的空格 # 运行结果:Inotonlyli%epython,but$lsoli%e%otlin. print(s.translate(table1))
在使用translate方法和maketrans方法时要了解如下几点:
(1)translate方法替换的不止一个字符,如果在原字符串中有多个字符满足条件,那么就替换所有满足条件的字符。
(2)maketrans方法的第3个参数指定了要从原字符串中删除的字符,不是字符串。如果第3个参数指定的字符串长度大于1,那么在删除字符时只会考虑其中的每个字符。例如,参数值为"ab",那么只会删除原字符串中的"a"或"b",包括在字符串中间出现的这些字符。
1.编写一个Python程序,从控制台输入一个字符串(保存到变量s中),然后通过while循环不断输入字符串(保存到变量subStr中),并统计subStr在s中出现的次数,最后利用format方法格式化统计结果。程序运行结果如图5-6所示。
答案位置: src/string/solution1.py
2.编写一个Python程序,从控制台输入一个整数(大于0),然后利用format方法生成一个星号三角形,如图5-7所示。
图5-6 统计子字符串在原字符串中出现的次数
图5-7 8层星号三角形
答案位置: src/string/solution2.py
3.通过控制台输入了位数等数值,通过format方法完成补0、对齐、填充字符、进制转换等操作。
答案位置: src/string/solution3.py
4.通过控制台输入一个大字符串,然后在while循环中不断输入一个子字符串、开始索引和结束索引,并根据输入的值在大字符串中查找子字符串,最后输出查找结果。如果输入的子字符串是"end",则退出循环。
程序运行结果如图5-8所示。
图5-8 通过find方法在大字符串中查找子字符串
答案位置: src/string/solution4.py
本章深入讲解了Python中字符串的核心操作。主要包括字符串格式化和字符串方法。其中字符串格式化是本章的重点。在Python语言中,可以通过字符串格式化操作符(%)、字符串模板、format方法、f字符串对字符串进行格式化,其中format方法的功能最强大,f字符串最简单。Python之所以在深度学习、网络爬虫等领域非常受欢迎,主要就是因为Python在文本处理方面功能强大,而字符串格式化就是文本处理的核心操作之一。当然,Python在其他方面也有非常强大的功能,如网络,这点在后面的章节就会体会到。