目录
一、字符串的驻留机制
字符串:在Python中字符串是基本数据类型,是一个不可变的字符串序列。
字符串驻留机制
- 仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新的空间,而是把该字符串的地址赋给新创建的变量。
示例:
# 驻留机制
a = 'Python'
b = "Python"
c = '''Python'''
print(a, b, c)
print(id(a))
print(id(b))
print(id(c))
运行结果:
驻留机制的几种情况(交互模式)
- 字符串的长度为0或1时
- 符合标识符的字符串
- 字符串只在编译时进行驻留,而非运行时
- [-5,256]之间的整数数字
以上驻留机制的几种情况可以用cdm去进行验证
sys中的intern方法强制2个字符串指向同一个对象
PyCharm对字符串进行了优化处理
字符串驻留机制的优缺点
- 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的。
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串的长度,然后再拷贝,只new一次对象,效率比“+”高。
二、字符串的常用操作
(1)字符串的查询操作
查询方法
- index(),查找子串substr第一次出现的位置,如果查找的子串不存在时,则会抛出ValueError
- rindex(),查找子串substr最后一次出现的位置,如果查找的子串不存在时,则会抛出ValueError
- find(),查找子串substr第一次出现的位置,如果查找的子串不存在时,则会返回-1
- rfind(),查找子串substr最后一次出现的位置,如果查找的子串不存在时,则会返回-1
示例:
s = 'hello,word'
'''当子串存在的情况时'''
print(s.index('lo')) # 查找子串第一次出现的位置
print(s.find('lo')) # 查找子串第一次出现的位置
print(s.rindex('lo')) # 查找子串最后一次次出现的位置
print(s.rfind('lo')) # 查找子串最后一次次出现的位置
'''当子串不存在时的情况'''
# print(s.index('k')) # 会抛出ValueError
print(s.find('k'))
# print(s.rindex('k')) # 会抛出ValueError
print(s.rfind('k'))
运行结果:
(2)字符串的大小写转换
大小写转换
- upper(),把字符串中所有字符都转换成大写字母
- lower(),把字符串中所有字符都转换成小写字母
- swapcase(),把字符串中所有大写字母转换成小写字母,把字符串中所有小字母都转换成大写字母
- capitalize(),把第一个字符转换成大写,把其余字符都转换成小写
- title(),把每个单词的第一个字符都转换成大写,把每个单词的剩余字符转换成小写
示例:
s = 'hello, Python'
# 把字符串中所有字符都转换成大写字母的两种写法
# 第一种写法
a = s.upper() # 字符串转换成大写后,地址会发生改变
print(a)
# 第二种写法
print(s.upper())
# 把字符串中所有字符都转换成小写字母
b = s.lower()
print(b)
# 把字符串中所有大写字母转换成小写字母,把字符串中所有小字母都转换成大写字母
c = s.swapcase()
print(c)
# 把第一个字符转换成大写,把其余字符都转换成小写
d = s.capitalize()
print(d)
# 把每个单词的第一个字符都转换成大写,把每个单词的剩余字符转换成小写
e = s.title()
print(e)
运行结果:
(3)字符串内容对齐操作
对齐操作
- center(),居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
- ljust(),左对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
- rjust(),右对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
- zfill(),右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身
示例:
s = 'Hello, Python'
'''居中对齐'''
print(s.center(20, '*')) # 设置填充字符
print(s.center(20)) # 默认填充字符为空格
print(s.center(10)) # 当设置的指定宽度小于实际宽度时返回原字符串
'''左对齐'''
print(s.ljust(20, '*'))
print(s.ljust(20))
print(s.ljust(10))
'''右对齐'''
print(s.rjust(20, '*'))
print(s.rjust(20))
print(s.ljust(10))
'''右对齐的另一种方法'''
print(s.zfill(20))
print(s.zfill(10))
'''出现负数的情况'''
s1 = '-1234'
print(s1.zfill(10))
运行结果:
(4)字符串的劈分(分隔)
split()
- 从字符串左边开始劈分,默认劈分的字符串是空格字符串,返回的值都是一个列表
- 以通过参数sep指定劈分字符串是劈分字符
- 通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大劈分之后,剩余的字符串会单独作为一部分
rsplit()
- 从字符串右边开始劈分,默认劈分的字符串是空格字符串,返回的值都是一个列表
- 以通过参数sep指定劈分字符串是劈分字符
- 通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大劈分之后,剩余的字符串会单独作为一部分
示例:
s = 'hello, word, cat'
# split(),从左边开始劈分
lst = s.split()
print(lst)
print(s.split()) # 默认劈分符
s1 = 'hello| word| cat'
print(s1.split(sep='|')) # 指定劈分符
print(s1.split(sep='|', maxsplit=1))
# rsplit(),从右边开始劈分
print(s.rsplit()) # 默认劈分符
print(s1.rsplit(sep='|'))
print(s1.rsplit(sep='|', maxsplit=1))
运行结果:
(5)字符串的判断
字符串的判断
- isidentifier(),判断指定的字符串是否是合法的标识符
- isspace(),判断指定的字符串是否全部是由空白字符组成(回车、换行、水平制表符)
- isalpha(),判断指定的字符串是否全部由字母组成
- isdecimal(),判断指定的字符串是否全部由十进制的数字组成
- isnumeric(),判断指定的字符串是否全部由数字组成
- isalnum(),判断指定的字符串是否全部由字母和数字组成
示例:
'''判断是否是合法的标识符'''
s = 'hello'
print('1.', s.isidentifier())
print('2.', 'hello,word'.isidentifier())
print('3.', '1234'.isidentifier())
'''判断指定的字符串是否是空白字符串'''
print('4.', '\t'.isspace())
print('5.', ' '.isspace())
'''判断指定的字符串是否全部为字母组成'''
print('6.', 'abcd'.isalpha())
print('7.', 'abc123'.isalpha())
print('8.', 'abc...'.isalpha())
'''判断指定的字符串是否全部由十进制的数字组成'''
print('9.', '1234'.isdecimal())
print('10.', '1234五'.isdecimal())
print('11.', 'ⅠⅡⅢⅣⅤ'.isdecimal())
'''判断指定的字符串是否全部由数字组成'''
print('12.', '1234'.isnumeric())
print('13.', '1234五'.isnumeric())
print('14.', 'ⅠⅡⅢⅣⅤ'.isnumeric())
'''判断指定的字符串是否全部由字母和数字组成'''
print('15.', '1234wu'.isalnum())
print('16.', '1234wu六'.isalnum())
print('17.', '123abc '.isalnum())
运行结果:
(6)字符串的替换与合并
字符串替换
- replace(),第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第三个参数指定最大替换次数
字符串合并
- join(),将列表或元组中的字符串合并成一个字符串
示例:
# 字符串替换
s = 'hello,word'
print(s.replace('word', 'cat'))
s1 = 'hello,word,word,word,cat,word'
print(s1.replace('word', 'dog', 3)) # 指定替换的最大次数
# 字符串合并
lst = ['hello', 'word'] # 列表合并
print('*'.join(lst))
t = ('hello', 'word') # 元组合并
print('*'.join(t))
运行结果:
(7)字符串的比较
使用运算符进行比较
运算符:>,>=,<,<=,==,!=
比较规则:首先比较两个字符串中的第一个字符都转换成,如果相等则继续比较下一个字符,依次比较下去,直到两个字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串的所有后续字符将不再被比较。
比较原理:两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到其指定字符的原始值。与内置函数ord对应的内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符。
示例:
print('apple' > 'app')
print('python' > 'word')
print(ord('p'), ord('w'))
print(chr(112), chr(119))
运行结果:
==和is的区别:
==判断的是值是否相等
is判断的是id是否相等
(8)字符串的切片操作
- 字符串是不可变类型
- 不具备增、删、改等操作
- 切片操作将产生新的对象
示例:
s = 'hello,word'
print(s[1:])
print(s[:8])
print(s[1:9:1])
print(s[:11:2])
运行结果:
(9)格式化字符串
(1)格式化字符串的方式
%作为占位符
- %s:将内容转换成字符串,放入占位位置
- %d:将内容转换成整数,放入占位位置
- %i:将内容转换为整数,放入占位位置
- % f:将内容转换呈浮点型,放入占位位置
{}做占位符
f-string格式化
示例:
name = '小明'
age = 10
# 第一种表示方式
print('我是%s,今年%d岁' % (name, age))
# 第二种表示方式
print('我是{0},今年{1}岁'.format(name, age))
# 第三种表示方式
print(f'我是{name},今年{age}岁')
运行结果:
(2)数字精度
使用辅助负号“md.nf”控制数据的宽度和精度
- d,控制宽度,设置的宽度小于数字自身,不生效
- f,控制精度,会进行小数的四舍五入
示例:
- %5d:表示将整数的宽度控制在5位
- %5.3f:表示将宽度控为5,将小数点精度设置为3
- 若所设置的宽度小于数字自身,那么则不会发生变化
示例:
- 数字3.14被设置为%5d,那么其运行结果为:[空格]3.14
- 数字3.1415926被设置为%5d,那么其运行结果则不会发生变化,依旧为3.1415926
示例:
'''表示精度和宽度的格式化占位符'''
print('----------')
print('%d' % 99) # %d表示宽度
print('%10d' % 90) # 表示宽度为你10
print('%.3f' % 3.1415926) # %.f表示精度
print('%5.3f' % 3.1415926) # 此时的宽度精度不会生效,理由:当设置的宽度小于自身,则不会生效
print('%10.3f' % 2.71828) # 表示宽度为10,小数点后3位
运行结果:
(10)字符串的编码转换
编码与解码的方式
编码:将字符串转换为二进制数据(bytes)
- 使用encode( )进行编码
解码:将bytes类型的数据转换成字符串类型
- 使用decode( )进行解码
示例:
s = '欢迎使用Python'
'''进行编码'''
print(s.encode(encoding='GBK')) # 在GBK的这种编码格式中,一个中文占两个字节
print(s.encode(encoding='UTF-8')) # 在UTF-8这种编码格式中,一个中文占三个字节
'''进行解码'''
byte = s.encode(encoding='GBK') # 编码
print(byte.decode(encoding='GBK')) # 解码
byte = s.encode(encoding='UTF-8') # 编码
print(byte.decode(encoding='UTF-8')) # 解码
运行结果: