PYTHON 学习第四章 之 使用字符串
前言
我是一个做java 编程的程序猿,程序猿中的语言不止一种,于是自学了python ,在我学习过程中记录一些笔记和心得,很荣幸你能看到我的博客,如果内容中有什么错误或意见,请下方留言。
学习过程中,我很容易带入java的语法和思想去学习python,虽然他们有共同之处,但是学习过程中我应该告诉自己,“不懂编程,从头开始”。
知识来源:
书本知识来源 :《python 基础教程 第三版》
视频知识来源: 《北京图灵学院》 python 讲师 ——永远只有十八岁的刘大拿

以及带我入门的 微信公众号 《python小课》
如果觉得我在打广告的童靴,恭喜你们答对了,《python小课》 是我 花了 9.9元买的体验课,也是我的python 路上的第一个引路者。至于为什么不在那学习?那是因为我穷,穷,穷。
但我并不想放弃,然后就在网易课程上看到了课程齐全还免费的 python 课程《免费Python全系列教程全栈工程师 - 网易云课堂》,随后也买了一本python书。
之所以要说这些 尤其是视频学习,首先作为一个编程人员,一名学习者应该做到 "吃水不忘挖井人”,关键别人又不收费。所以我这样做,觉得过分的朋友,见谅。
字符串的基本操作
之前讲过,所有标准序列操作(索引,切片,乘法,成员资格检查,长度,最小值和最大值)都适用于字符串,但是字符串是不可变的,因此所有的元素赋值和切片赋值都是非法的。
str ='hello' print(str[0:1]='h2') #运行结果 File "D:/develTools/PycharmProjects/project1/venv/Include/test3.py", line 2 print(str[0:1]='h2') ^ SyntaxError: keyword can't be an expression
字符串格式:基础版
python 提供了多种字符串格式设置方法,今天先了解一个简单的——百分号(%)。%右边需要指定一个类型
| 序号 | 名称 | 说明 |
| %s | 字符串格 | 表示设置格式的必须为字符类型,否则将无法运行 |
| %d | 整数 | 表示设置的格式必须为整数,否则将无法执行 |
| %.3f | 浮点数 | 表示设置3位小数的浮点数 |
%s 字符串格式化 (必须为字符串,若不是则用 str() 转为 字符串)
name ='王富贵' print('%s同学真是一个好孩子,总是喜欢乐于助人'%(name)) #运行结果 王富贵同学真是一个好孩子,总是喜欢乐于助人
%d 整数格式化(不能字符类型,否则用 int()进行转换)
name ='王富贵' mothon = 6 print('%s同学真是一个好孩子,总是喜欢乐于助人'%(name)) print('在%d月考试中,获得了第一名'%(mothon)) #运行结果 王富贵同学真是一个好孩子,总是喜欢乐于助人 在6月考试中,获得了第一名
%.nf 浮点数格式化(同样也是不能为字符类型)
name ='王富贵' mothon = 6 total =564.5 print('%s同学真是一个好孩子,总是喜欢乐于助人'%(name)) print('在%d月考试中,获得了第一名'%(mothon)) print('他的总分是%.2f'%(total)) #运行结果 王富贵同学真是一个好孩子,总是喜欢乐于助人 在6月考试中,获得了第一名 他的总分是564.50
Template 关键字参数格式化:关键字参数可视为一种向命名替换字段提供值方式,如案例:
from string import Template age =18 gender = '男' name ='王富贵' hobby =['唱','跳','rap','篮球'] temp = Template('大家好,我叫$name,今年$age,我一名快乐的$gender,我爱好很多,如$hobby') print(temp.substitute(name=name,age=age,gender=gender,hobby=hobby)) #运行结果 大家好,我叫王富贵,今年18,我一名快乐的男,我爱好很多,如['唱', '跳', 'rap', '篮球']
索引格式化,这样的方式比 关键字更简单,更灵活 需要使用 format 函数
我们需要格式为四个地方,但是实际上我们只要填写三个就可以了,虽然关键字也能做到这一点,但是比起索引的方式,显得麻烦不少。可读性也不是很好。
str=''' 静夜思 李 白 床 前 {0} 光, 疑 是 {1} 霜。 举 头 望 {0}, {2} 思 故 乡。 ''' print(str.format('明 月','地 上','低 头')) #运行结果 静夜思 李 白 床 前 明 月 光, 疑 是 地 上 霜。 举 头 望 明 月, 低 头 思 故 乡。
我们再讲讲 format 的关键字 ,与 Template 不同的时,format 不是使用 $ 而是使用 {} 的方式,执行方式 Template 类似 ( k=v)
str="my name is {name}" print(str.format(name='王富贵')) #运行结果 my name is 王富贵
注:值得注意的是,关键字是无关顺序的,只要赋予相对应的字段(k=v)就行。
str='my name is {name}, 今年 {age}' print(str.format(age=18,name='王富贵')) #运行结果 my name is 王富贵, 今年 18
在python 3.6中,如果变量与替换字段同名,还可以使用一种简写。在字符串前 加上 f
看看不加 f 的效果
name='王富贵' str = 'name is {name}' print(str) #运行结果 name is {name}
有了 f buffer 加持后... 居然连 format 函数都可以不用了。
name='王富贵' str = f'name is {name}' print(str) #运行结果 name is 王富贵
不过这种简写方式,是要顺序的,必须变量定义 在 字符串的前面。而 format 则不用考虑这些。
字符串格式:进阶版
字符串格式涉及的内容有很多,即便是在这里也无法全面探索所有的细节,而只是介绍主要的组成部分。这里的基本思想是对字符串调用format,并提供要设置其格式的值。字符串包含有关设置的信息,而这些信息是使用一种微型格式指定语言(mini-language)
指定的。每个值都被插入字符串中,以替换用花括号括起来的替换字段。要在最终结果中包含花括号,可在格式字符串中使用两个花括号(即{{或}})来指定。
str="{{hello python}}".format() print(str) #运行结果 {hello python}
还真是必须要用两个 花括号,要不然大大的异常就行下面挂着。(说实话现在的我一脸蒙蔽,这是什么跟什么什么啊。。。埋头苦干就是干)
str="{hello python}".format() print(str) #运行结果 Traceback (most recent call last): File "D:/develTools/PycharmProjects/project1/venv/Include/test3.py", line 2, in <module> str="{hello python}".format() KeyError: 'hello python'
在格式字符串中,最激动人心的部分为替换字段,替换字段由如下部分组成,其中每个部分都是可选的(以下是书中原话)。
- 字段名:索引或标识符,指出要设置哪个指的格式并使用结果来替换该字段,除指定值外,还可指定值的特定部分,如列表的元素。
- 转换标志:跟在叹号后面的单个字符。当前支持的字符包括 r(表示repr),s(表示)和 a(表示ascii)。如果你指定了转换标志,将不能使用对象本身的格式转设置机制,而是使用指定的函数将对象转换为字符串,再做进一步的格式设置。
- 格式说明符:跟在冒号后面的表达式(这种表达式是使用微型格式指定语言表示的)。格式说明符让我们能够详细地指定最终的方式,包括格式类型(字符串,浮点数或十六进制数),字段宽度和数的精度,如何显示符号和千位分隔符,以及各种对齐和填充方式。
替换字段名
在最简单的情况下,只需向format 提供要设置其格式的未命名参数,并在格式字符串中使用未名参数。并按照顺序将字段和参数进行匹对。也可以指定参数名称,对指定参数进行赋值。最重要的是他们可以混合使用,但是无参数名称需要顺序(无参需要写到前面)。
str=''' 我叫 {name} 来自{} 今年{age} 我的梦想是{} ''' print(str.format("肯尼亚亚麻省法西利市",'称霸韩国',name='王富贵',age=18)) #运行结果 我叫 王富贵 来自肯尼亚亚麻省法西利市 今年18 我的梦想是称霸韩国
那为什么说午餐需要顺序?因为语法就不支持
str=''' 我叫 {name} 来自{} 今年{age} 我的梦想是{} ''' print(str.format("肯尼亚亚麻省法西利市",name='王富贵','称霸韩国',age=18)) #运行结果 print(str.format("肯尼亚亚麻省法西利市",name='王富贵','称霸韩国',age=18)) ^ SyntaxError: positional argument follows keyword argument
切记注意,无参要按照顺序排在前面,有参排在午餐后面,但是有参与有参之间可以不考虑顺序问题
str=''' 我叫 {name} 来自{} 今年{age} 我的梦想是{} ''' print(str.format("肯尼亚亚麻省法西利市",'称霸韩国',age=18,name='王富贵')) #运行结果 我叫 王富贵 来自肯尼亚亚麻省法西利市 今年18 我的梦想是称霸韩国
列表索引
如果上面那种方式让我们的程序变得混乱不堪(无参看起来可读性却是不太好,两者结合可读性更差)。字符串格式化,还支持列表结构,感觉确实干净了些。
studentInfo=[[1001,'王富贵',18,'男','三班',265],[1002,'李村花',16,'女','一班',465],[1003,'菲甜甜',18,'女','二班',654]] for k in studentInfo: info = ''' 学号: {no[0]},姓名 {name[1]},年龄 {age[2]},性别 {sex[3]},班级 {clazz[4]},得分 {total[5]} ''' print(info.format(no=k,total=k,name=k,age=k,clazz=k,sex=k)) #运行结果 学号: 1001,姓名 王富贵,年龄 18,性别 男,班级 三班,得分 265 学号: 1002,姓名 李村花,年龄 16,性别 女,班级 一班,得分 465 学号: 1003,姓名 菲甜甜,年龄 18,性别 女,班级 二班,得分 654
如果列表中 字段太多了,不想定义参数名称 同样也支持无参的方式,但是每个位置都需要给上 列表
studentInfo=[[1001,'王富贵',18,'男','三班',265],[1002,'李村花',16,'女','一班',465],[1003,'菲甜甜',18,'女','二班',654]] for k in studentInfo: info = ''' 学号: {[0]},姓名 {[1]},年龄 {[2]},性别 {[3]},班级 {[4]},得分 {[5]} ''' print(info.format(k,k,k,k,k,k)) #运行结果 学号: 1001,姓名 王富贵,年龄 18,性别 男,班级 三班,得分 265 学号: 1002,姓名 李村花,年龄 16,性别 女,班级 一班,得分 465 学号: 1003,姓名 菲甜甜,年龄 18,性别 女,班级 二班,得分 654
基本转换:
指定要在字段中包含的值后,就可添加有关如何设置其格式的指令了。首先可以提供转换标志,书上将这里到时候,我半天没明白什么意思。
书上的案例是这样的
>>> print("{pi!s} {pi!r} {pi!a}".format(pi="π")) >>> π 'π' '\u03c0'
想了半天后 原来是对转义字符的格式化啊(扎心...) 很奇怪的是,为什么 \u 在只发出中或报错。 必须 \\u,了解的朋友下方留言
str='{value!s},{value!r},{value!a}' print(str.format(value="我\000们")) #运行结果 我 们,'我\x00们','\u6211\x00\u4eec'
上面的三个标志(s,r,a)分别是指str,repr,ascii进行转换。str 和 repr 之前提到过,str 只是普通字符串,会被转义符影响,而 repr 会将字符串原样输出。ascii 就是 ASCII 表示。
除了这些还可以指定要转换的值的类型,更准确的说是将他指定为某种类型。我们拿 整数 和 浮点数举例。
语法:{参数名 :类型} 参数名可以不给
numstr="{value}" print(numstr.format(value=18)) #运行结果 18 numstr="{value:d}" print(numstr.format(value=18)) #运行结果 18 numstr="{value:f}" print(numstr.format(value=18)) #运行结果 18.000000
numstr="{d}"
print(numstr.format(18))
#运行结果
18
字符串格式设置中的类型说明符
| 序号 | 类型 | 含义 |
| 1 | b | 将整数表示为二进制数 |
| 2 | c | 将整数解读为Unicode码点 |
| 3 | d | 将整数视为十进制数进行处理,这是整数默认使用的说明符 |
| 4 | e | 使用科学表示法来表示小数(用e来表示指数) |
| 5 | E | 与e相同,但使用E来表示指数 |
| 6 | f | 将小数表示为浮点数 |
| 7 | F | 与f相同,但对于特殊值(nan和inf),使用大写表示 |
| 8 | g | 自动在顶点表示法和科学表示法之间做出选择。这是默认用于小时的说明符,但在默认情况下至少有一位小数 |
| 9 | G | 与g相同,但使用大写来表示指数和特殊值 |
| 10 | n | 与g相同,但插入随区域而异的数字分隔符 |
| 11 | o | 将整数表示为八进制 |
| 12 | s | 保持字符串的格式不变,这是默认的用于字符串的说明符 |
| 13 | x | 将整数表示为十六进制数并使用小写字母 |
| 14 | X | 与x相同,但使用大写字母 |
| 15 | % | 将数表示为百分比值(乘以100,按说明符f设置格式,再在后面加上% |
宽度、精度和千位分隔符
设置浮点数(或其他更具体的小数类型)的格式时,默认在小数点后面显示 6 小数 ,并根据需要设置字段的宽度,而不进行任何形式的填充。当然,这是默认情况下的,但是可以根据需求指定宽度和精度。
宽度使用整数指定,如下所示:
#--------------------数字------------- # repr 看得更直观一点 str='{num:10}' print(repr(str.format(num=5))) #运行结果 ' 5' #--------------------字符------------- # repr 看得更直观一点 str='{str:10}' print(repr(str.format(str='hello'))) #运行结果 'hello '
为什么 数字和 字符指定宽度后,位置不一样呢?数字时靠右,字符是靠左。不过不用担心,他们的位置是可以指定的(居左、居中、居右)待会聊....
精度也是使用整数指定的,但需要在前面加上一个表示小数点的句点(f)。如下所示,2f 表示将小数保留2位小数
numstr="{num:.2f}" print(numstr.format(num=4.3624)) #运行结果 4.36
当然,可同时指定宽度和精度 10表示 宽度为10 ,2表示 保留两位小数 ,f 表示浮点数。
numstr="{num:10.2f}" print(repr(numstr.format(num=4.3624))) #运行结果 ' 4.36'
我们再看看 字符串指定精度(类似截取)
str='{:.5}' print(str.format("hello python")) #运行结果 hello
最后再看看看 千位分隔符 用 , 表示。
mayun='我的钱大概有:{:,.3f}亿' print(mayun.format(1000*10000)) #运行结果 我的钱大概有:10,000,000.000亿
如果要使用随区域而异的千位分隔符,应该使用说明符n
符号、对齐和零填充
有很多用于设置数字格式的机制,比如便于打印整齐的表格。在大多数情况下,只需要指定宽度和精度,但包含负数后,原本漂亮的输出可能不再漂亮了。另外字符和数字的默认对齐方式不同,你可能想修改默认的对齐方式,在指定宽度和精度的前面,
可添加一个标志。这个表示可以是零、加号、减号或空格,其中零表示使用0来填充数字。
如下所示:
str="{num:010.2f}" print(str.format(num=4.23)) #运行结果 0000004.23
注意:虽然是甚至的长度用0占位,但是并不是说可以用其他字符填充(不能用字符),除了0是填充以外,其他数字都是表示长度为 x, 然后用空格进行填充(亲测出来的)
str="{num:11.2f}" print(repr(str.format(num=+4.23))) #运行结果 ' 4.23'
还有注意时,给一个0 如{num:0.2f},没啥子表示的,就是和普通运行出来的一样结果
str="{num:0.2f}" print(repr(str.format(num=+4.23))) #运行结果 '4.23'
然后看看 + 和 - 号 有啥不一样 (贴一下运行结果吧)
str="{num:-0.2f}" print(repr(str.format(num=4.23))) #运行结果 '4.23' str="{num:+0.2f}" print(repr(str.format(num=4.23))) #运行结果 '+4.23' str="{num:+0.2f}" print(repr(str.format(num=-4.23))) #运行结果 '-4.23'
要指定对齐方式 可以使用 <(左对齐)、^(居中)、>(右对齐)。
如图所示 定义一张学生表格
table ="{:<10}{:^8}{:>10}" body1="{:<10}{:^10}{:>10}" body2="{:<10}{:^10}{:>10}" print(table.format('学号','姓名','班级')) print(body1.format('101','村花','一班')) print(body2.format('102','富贵','二班')) #运行结果 学号 姓名 班级 101 村花 一班 102 富贵 二班 Process finished with exit code 0
再中间加上性别和年龄 看看效果(结果我也不知道)
table ="{:<10}{:^8}{:^8}{:^8}{:>10}" body1="{:<10}{:^10}{:^10}{:^8}{:>10}" body2="{:<10}{:^10}{:^10}{:^8}{:>10}" print(table.format('学号','姓名','性别','年龄','班级')) print(body1.format('101','村花','女','16','一班')) print(body2.format('102','富贵','男','18','二班')) #运行结果 学号 姓名 性别 年龄 班级 101 村花 女 16 一班 102 富贵 男 18 二班
可以使用填充字符来扩充对齐说明符,这样将使用指定的字符而不是默认的空格来填充。
如下所示,其他的应该也是差不多的操作,我也难得写了。
str="{:$^20}" print(str.format('无法无天')) #运行结果 $$$$$$$$无法无天$$$$$$$$
需要介绍的最后一个要素是井号(#)选项,你可以将其放在符号说明符和宽度之间(如果制定了这种两种设置)。这个选项将触发另一个转换方式,转换细节随类而异。例外,对于二进制,八进制,十六进制转换,将加上一个前缀。
二进制
num='{:b}' print(num.format(36)) #运行结果 100100 num='{:#b}' print(num.format(36)) #运行结果 0b100100
八进制
num='{:o}' print(num.format(36)) #运行结果 44 num='{:#o}' print(num.format(36)) #运行结果 0o44
字符串方法
前面介绍了列表的方法,而字符串的方式要多得多,因为很多方法都是从模块string哪里”继承“而来。(在较早的python版本中,这些方法为模块string中的函数,如果需要,现在依然可以使用到这些函数)。
模块string
虽然字符串方法完全盖住了模块string的风头,但这个模块包含一些字符串没有的常量和函数。下面介绍就是string模板中几个常用的常量
- string.digits:包含数字0~9的字符串
import string print(string.digits) #运行结果 0123456789
- string.ascii_letters:包含所有ASCII字母(大写和小写)的字符串
import string print(string.ascii_letters) #运行结果 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
- string.ascii_lowercase:包含所有小写SACII字母的字符串
import string print(string.ascii_lowercase) #运行结果 abcdefghijklmnopqrstuvwxyz
- string.printable:包含所有可打印的ASCII字符的字符的字符串
import string print(string.printable) #运行结果 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
- string.punctuation:包含所有ASCII标点字符的字符串
import string print(string.punctuation) #运行结果 !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
- string.ascii_uppercase:包含所有大写ASCII字母的字符串
import string print(string.ascii_uppercase) #运行结果 ABCDEFGHIJKLMNOPQRSTUVWXYZ
- 更多 stirng模块 常量 参考 (help(string))
虽然说的是ASCII 字符,但值实际上是未解码的Unicode字符串。
字符串方法
- center:通过在两边添加填充字符(默认为空格)让字符串居中
- find:在子串中查找子串,如果找到,就返回子串的第一个字符的索引,否则返回-1。
- join:用于合并序列的元素
- lower:返回字符串的小写版本
- replace:将指定子串都替换为另一个字符串中,并返回替换后的结果
- split:用于将字符串拆分为序列
- strip:将字符串开头和末尾的空白(但不包括中间的空白)删除,并返回删除后的结果
- translate:与replace一样替换字符串的特定部分,但不同的是它只能进行单字符替换。这个方法的优势在于能够同时替换多个字符,因此效率比replace高。

浙公网安备 33010602011771号