一、字符串的定义
在python中字符串是基本数据类型,是一个不可变的字符序列
二、字符串驻留机制
1、仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
2、驻留机制的几种情况(交互模式)
- 字符串的长度为0或1时
- 符合标识符的字符串(只含有数字、字母和下划线的)
- 字符串只在编译时进行驻留,而非运行时
- [-5,256]之间的整数数字
3、sys中的intern方法强制两个字符串指向同一个对象 a=sys.intern(b)
4、 pycharm对字符串进行了优化处理
5、驻留机制的优缺点
- 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串的长度,然后再拷贝,只new一次对象,效率比+高
三、字符串的常用操作
1、字符串的查询操作
- index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
- rindex() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
- find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
- rfind() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1
s='hello,hello' print(s.index('lo')) #3 print(s.find('lo')) #3 print(s.rindex('lo')) #9 print(s.rfind('lo')) #9 #print(s.index('k')) #ValueError: substring not found print(s.find('k')) #-1 推荐使用find方法,因为不会抛出异常 #print(s.rindex('k')) #ValueError: substring not found print(s.rfind('k')) #-1
2、字符串的大小写转换操作
- upper() 把字符串中所有字符都转换为大写字母
- lower() 将字符串中所有字符都转换为小写字母
- swapcase() 把字符串中所有大写字母都转为小写字母,把所有小写字母都转为大写字母
- capitalize() 把第一个字符转换为大写,把其余字符转换为小写
- title() 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写
s='hello,python' a=s.upper() #转成大写之后,会产生一个新的字符串对象 print(a,id(a)) #HELLO,PYTHON 2190238932592 print(s,id(s)) #hello,python 2190239780464 print(s.lower(),id(s.lower())) #hello,python 2553764040496 转换之后,也会产生一个新的字符串对象 b=s.lower() print(b==s) #True 内容一样 print(b is s) #False 内存存储地址不同 s2='hello,Python' print(s2.swapcase()) #HELLO,pYTHON print(s2.title()) #Hello,Python
3、字符串内容对齐操作
- center() 居中对齐,第一个参数指定宽度,第二个参数指定填充符,第二个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
- ljust() 左对齐,同上
- rjust() 右对齐,同上
- zfill() 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小与等于字符串的长度,则返回字符串本身
s='hello,python' print(s.center(20,'*')) #****hello,python**** #左对齐 print(s.ljust(20,'*')) #hello,python******** print(s.ljust(20)) #hello,python print(s.ljust(10)) #hello,python #右对齐 print(s.rjust(20,'*')) #********hello,python print(s.rjust(20)) # hello,python print(s.rjust(10)) #hello,python #右对齐,使用0填充 print(s.zfill(20)) #00000000hello,python print(s.zfill(10)) #hello,python print('-8910'.zfill(8)) #-0008910
4、字符串劈分操作
- split() 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表; 通过参数sep指定劈分字符串是的劈分符,通过参数maxsplit指定劈分字符串的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独作为一部分
- rsplit() 从字符串的右边开始劈分,另外同上
s='hello world python' lst=s.split() print(lst) #['hello', 'world', 'python'] s1='hello|world|python' print(s1.split(sep='|')) #['hello', 'world', 'python'] print(s1.split(sep='|',maxsplit=1)) #['hello', 'world|python'] #从右侧开始劈分 print(s1.rsplit(sep='|')) #['hello', 'world', 'python'] print(s1.rsplit(sep='|',maxsplit=1)) #['hello|world', 'python']
5、判断字符串操作
- isidentifier() 判断指定的字符串是不是合法的标识符
- isspace() 判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符)
- isalpha() 判断指定的字符串是否全部由字母组成
- isdecimal() 判断指定的字符串是否全部由十进制的数字组成
- isnumerical() 判断指定的字符串是否全部由数字组成(数字包括罗马数字,中文数字等)
- isalnum() 判断指定的字符串是否全部由字母和数字组成
s='hello,python' print(s.isidentifier()) #False 因为有逗号 print('hello'.isidentifier()) #True print('\n'.isspace()) #True print('zhangsan'.isalpha()) #True print('123四'.isdecimal()) #False print('123四'.isnumeric()) #True print('Ⅱ'.isnumeric()) #True print('②'.isnumeric()) #True print('张三1'.isalnum()) #True print('abc!'.isalnum()) #False
6、字符串的替换与合并
- 字符串的替换 replace() 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方式时可以通过第三个参数指定最大替换次数
s='hello,python' print(s.replace('python','java')) #hello,java s1='hello,python,python,python' print(s1.replace('python','java',2)) #hello,java,java,python
- 字符串的合并 join() 将列表或者元组中的字符串合并成一个字符串
lst=['hello','java','python'] print("|".join(lst)) #hello|java|python print(" ".join(lst)) #hello java python t=('hello','java','python') print("".join(t)) #hellojavapython print("*".join('python')) #p*y*t*h*o*n
四、字符串的比较操作
1、运算符:>,>=,<,<=,==,!= (==比较的是value,is比较的是id 注意字符串有驻留机制)
2、比较规则
首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较
3、比较原理
两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符。
print('apple'>'app') #True print('apple'>'banana') #False print(ord('a'),ord('b')) #97 98 print(chr(97),chr(98)) #a b
五、字符串的切片操作 [start : end : step]
字符串是不可变类型,不具备增、删、改等操作,切片操作将产生新的对象;
如果步长step为正数,则是从左往右,如果步长step为负数,则是从右往左
s='hello,python' s1=s[:5] s2=s[6:] s3='!' newstr=s1+s3+s2 print(newstr) #hello!python print(s[0::2]) #hlopto print(s[::-1]) #nohtyp,olleh print(s[-6::1]) #python
六、格式化字符串
1、% 占位符 元组
name='张三' age=20 print('我叫%s,今年%d' % (name,age)) #我叫张三,今年20
2、{} 占位符 format()方法
print('我叫{0},今年{1}'.format(name,age)) #我叫张三,今年20
3、f-string
print(f'我叫{name},今年{age}岁') #我叫张三,今年20岁
4、宽度和精度
print('%10d' % 99) # 99 10表示的是宽度 print('%.3f' % 3.1415926) #3.142 四舍五入 .3表示的是精度 print('%10.3f' % 3.1415926) # 3.142 print('{0}'.format(3.1415926)) #3.1415926 print('{0:.3}'.format(3.1415926)) #3.14 .3表示的是一共是3位数 print('{0:.3f}'.format(3.1415926)) #3.142 .3f表示的是3位小数 print('{0:10.3f}'.format(3.1415926)) # 3.142
七、字符串的编码与解码(爬虫会用到)
s='天涯共此时'
1、编码
print(s.encode(encoding='GBK')) #在GBK编码格式中,一个中文占用两个字节 b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1' print(s.encode(encoding='UTF-8')) #在UTF-8编码格式中,一个中文占用三个字节 b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
2、解码
byte代表一个二进制数据(字节类型的数据)
byte=s.encode(encoding='GBK') print(byte.decode(encoding='GBK')) #天涯共此时 byte1=s.encode(encoding='UTF-8') print(byte1.decode(encoding='UTF-8')) #天涯共此时