作为新手自学Python的第八天,技术低微,希望可以通过这种方式督促自己学习。
个人学习环境:python3.9,PyCharm 2021.3.2 (Community Edition)
———————————————————————————————————————————
在Python中字符串是基本数据类型,是一个不可变的字符序列(目前所学不可变序列有:元组、字符串)
第一种 | 单引号' ' |
---|---|
第二种 | 双引号" " |
第三种 | 三引号''' ''' |
a = 'Python'
b = "Python"
c = '''Python'''
# 三引号是可换行字符串,字符串不赋值给变量,可以当做注释使用
# 具体三单引号与三双引号可查看此篇文档http://t.csdn.cn/sCOvz
字符串驻留是一种在内存中仅保存一份相同且不可变字符串的方法。 Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量。
a = 'Python'
b = "Python"
c = '''Python'''
print(a, id(a))
print(b, id(b))
print(c, id(c))
"""
结果为:
Python 2462425264432
Python 2462425264432
Python 2462425264432
"""
字符串的长度为0或1
符合标识符的字符串
字符串只在编译时进行驻留,而非运行时
[-5,256]之间的整数数字
# 这里代码需要使用cmd进行运行,Pycharm运行都是True,是因为Pycharm对字符串进行了优化处理
# 字符串长度为0或1
s1 = ''
>>> s2 = ''
>>> s1 is s2
True
>>> s1 = '%'
>>> s2 = '%'
>>> s1 is s2
True
# 符合标识符的字符串
>>> s1 = 'abc%'
>>> s2 = 'abc%'
>>> s1 is s2
False
>>> s1 == s2
True
>>> id(s1)
2318579417904
>>> id(s2)
2318579417968
>>> s1 = 'abcd'
>>> s2 = 'abcd'
>>> s1 is s2
True
>>> s1 == s2
True
>>> id(s1)
2318579418032
>>> id(s2)
2318579418032
# 字符串只在编译时进行驻留,而非运行时
>>> a = 'abc'
>>> b = 'ab'+'c'
>>> c = ''.join(['ab','c'])
>>> a is b
True
>>> a is c
False
>>> c
'abc'
>>> type(c)
>>> a
'abc'
>>> type(a)
#a、b在程序编译时就已经是'abc',而c是在运行时才通过join方法转为'abc'
# [-5,256]之间的整数数字
# 为什么是[-5,256]这个区间,可以参考Python中神秘的-5到256 - Jerry Jho的文章 - 知乎 https://zhuanlan.zhihu.com/p/33907983
>>> a = -5
>>> b = -5
>>> a is b
True
>>> a = -6
>>> b = -6
>>> a is b
False
标识符的基本使用规则:
在python里,标识符有字母、数字、下划线组成。
在python中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。
python中的标识符是区分大小写的。
sys中的intern方法强制2个字符串指向同一个对象
# 依旧使用cmd运行
>>> import sys
>>> s1 = 'abc%'
>>> s2 = 'abc%'
>>> s1 is s2
False
>>> s1 = sys.intern(s2)
>>> s1 is s2
True
当需要值相同的字符串时可以直接从池中拿来使用,避免了频繁的创建和销毁,提升效率和节约内存。
拼接字符串和修改字符串会比较影响性能。
在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()是先计算出所有字符中的长度,然后再拷贝,其中只new一次对象,效率比“+”高
方法名称 | 说明 |
---|---|
index() | 查找子串第一次出现的位置,如果不存在,则报错 |
rindex() | 查找子串最后一次出现的位置,如果不存在,则报错 |
find() | 查找子串第一次出现的位置,如果不存在,则返回-1 |
rfind() | 查找子串最后一次出现的位置,如果不存在,则返回-1 |
s = 'hello,hello' print(s.index('lo')) # 3 print(s.find('lo')) # 3 print(s.rindex('lo')) # 9 print(s.rfind('lo')) # 9
方法名称 | 说明 |
---|---|
upper() | 字符串中所有字符转为大写 |
lower() | 字符串中所有字符转为小写 |
swapcase() | 字符串中所有大小写互换,大写转为小写,小写转为大写 |
capitalize() | 第一个字符转为大写,其余字符转为小写 |
title() | 每个单词的第一个字符转为大写,每个单词剩余字符转为小写 |
转换之后会产生一个新的字符串
方法名称 | 说明 |
---|---|
center() | 居中对齐,第1个参数指定宽度,第2个参数指定填充符 |
ljust() | 左对齐,第1个参数指定宽度,第2个参数指定填充符 |
rjust() | 右对齐,第1个参数指定宽度,第2个参数指定填充符 |
zfill() | 右对齐,左边用0填充 |
对于center()、ljust()、rjust()来说,第2个参数可选,默认为空格。如果设置的宽度小于实际宽度则返回原字符串
对于zfill(),只接收一个参数用于指定字符串的宽度,如果制定的宽度小于等于字符串的长度,则返回字符串本身
# 居中
s = 'hello,Python'
print(s.center(20, '*'))
# 左对齐
print(s.ljust(20, '*'))
print(s.ljust(10))
print(s.ljust(20))
# 右对齐
print(s.rjust(20, '*'))
print(s.rjust(20))
print(s.rjust(10))
# zfill()
print(s.zfill(20))
print(s.zfill(10))
print('-8910'.zfill(8))
"""
结果为:
****hello,Python****
hello,Python********
hello,Python
hello,Python
********hello,Python
hello,Python
hello,Python
00000000hello,Python
hello,Python
-0008910
"""
方法名称 | 说明 |
---|---|
split() | 从字符串的左边开始分割,默认的分割字符为空格,返回的值都是一个列表 |
以通过参数sep指定分割字符串 | |
通过参数maxsplit指定分割字符串时的最大分割次数,经过最大次分割之后,剩余的字串单独为一部分 | |
rsplit() | 从字符串的右边开始分割,默认的分割字符为空格,返回的值都是一个列表 |
以通过参数sep指定分割字符串 | |
通过参数maxsplit指定分割字符串时的最大分割次数,经过最大次分割之后,剩余的字串单独为一部分 |
s = 'hello world Python'
lst = s.split()
print(lst)
s1 = 'hello|world|python'
print(s1.split(sep='|'))
print(s1.split(sep='|', maxsplit=1))
"""
结果为:
['hello', 'world', 'Python']
['hello', 'world', 'python']
['hello', 'world|python']
"""
# rsplit()从右侧开始分割
# rsplit()从右侧开始分割
print(s.rsplit())
print(s1.rsplit('|'))
print(s1.rsplit(sep='|', maxsplit=1))
"""
结果为:
['hello', 'world', 'Python']
['hello', 'world', 'python']
['hello|world', 'python']
"""
方法名称 | 说明 |
---|---|
isidentifier() | 判断指定的字符串是不是合法的标识符 |
isspace() | 判断指定的字符串是否全部由空白字符组成(回车、换行,水平制表符) |
isalpha() | 判断指定的字符串是否全部由字母组成 |
isdecimal() | 判断指定字符串是否全部由十进制的数字组成 |
isnumeric() | 判断指定的字符串是否全部由数字组成 |
isalnum() | 判断指定字符串是否全部由字母和数字组成 |
# 判断字符串是否合法
s = 'hello,Python'
print('1.', s.isidentifier()) # 1.False
print('2.', 'hello'.isidentifier()) # 2.True
print('3.', '张三_'.isidentifier()) # 3.True
print('4.', '张三_123'.isidentifier()) # 4.True
# 判断字符串是否全由空白字符组成
print('5.', '\t'.isspace()) # 5.True
# 判断字符串是否全由字母组成
print('6.', 'abc'.isalpha()) # 6.True
print('7.', '张三'.isalpha()) # 7.True
print('8.', '张三1'.isalpha()) # 8.False
# 判断字符串是否全由十进制数字组成
print('9.', '123'.isdecimal()) # 9.True
print('10.', '123四'.isdecimal()) # 10.False
print('11.', 'ⅢⅢⅢ'.isdecimal()) # 11.False
# 判断字符串是否全由数字组成
print('12.', '123'.isnumeric()) # 12.True
print('13.', '123四'.isnumeric()) # 13.True
print('14.', 'ⅢⅢⅢ'.isnumeric()) # 14.True
# 判断字符串是否全由字母和数字组成
print('15.', 'abc1'.isalnum()) # 15.True
print('16.', '张三123'.isalnum()) # 16.True
print('17.', 'abc!'.isalnum()) # 17.False
功能 | 方法名称 | 说明 |
---|---|---|
字符串替换 | replace() | 第一个参数指定被替换的子串,第二个参数指定替换子串的字符串,返回替换后得到的字符串 |
字符串合并 | join() | 将列表或元组中的字符串合并成一个字符串 |
replace()方法中,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数
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
"""
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
"""
lst = ['hello', 'java', 'python']
print('|'.join(lst))
print(''.join(lst))
"""
结果为:
hello|java|python
hellojavapython
"""
t = ('hello', 'java', 'python')
print(''.join(t))
"""
结果为:
hellojavapython
"""
print('*'.join('Python'))
"""
结果为:
P*y*t*h*o*n
"""
运算符:>,>=,<,<=,==,!=
规则:先比较两个字符串中第一个字符,如果相等则继续比较下一个字符,依次进行比较,直到两个字符串中的字符不相等后,其比较结果就是两个字符串的比较结果,两个字符串的所有后续字符将不再被比较
原理:两字符比较时,比较的是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
== 与 is 的区别
== 比较的是value
is 比较的是id是否相等
字符串是不可变类型:不具备增、删、改等操作
切片将产生新的对象
s = 'hello,Python'
s1 = s[:5] # 没有指定起始位置,从0开始
s2 = s[6:] # 没有指定结束位置,一直到最后元素
s3 = '!'
newstr = s1 + s3 + s2
print(s1)
print(s2)
print(newstr)
# 完整写法[start:stop:step]
print(s[1:5:1])
print(s[::2])
print(s[::-1]) # 默认从最后一个元素开始
print(s[-6::1]) # 索引从-6开始,一直到最后
第一种:%做占位符
第二种:{}做占位符(format方法格式化)
第三种:f-string(python3.6引入了一种新的字符串格式化方式:f-string格式化字符串。值得注意的是,f-string就是在format格式化的基础之上做了一些变动,核心使用思想和format一样)
name = '张三'
age = 20
print('我叫%s,今年%d岁' % (name, age))
print('我的名字叫{0},今年{1}岁'.format(name, age))
# f-string
print(f'我叫{name},今年{age}岁')
设置宽度和精度
print('%d' % 99)
print('%10d' % 99) # 10表示宽度
print('%f' % 3.1415926)
print('%.3f' % 3.1415926) # .3表示小数点后三位
print('%10.3f' % 3.1415926) # 总宽度为10,小数点后3位
print('{0}'.format(3.1415926))
print('{0:.3}'.format(3.1415926)) # .3表示一共是3位数
print('{0:.3f}'.format(3.1415926)) # .3f表示3位小数
print('{0:10.3f}'.format(3.1415926)) # 宽度是10,3位小数
数据传输所用,在传输中字符串转为二进制,传输后二进制转为字符串
编码:将字符串转换为二进制数据(bytes)
解码:将bytes类型的数据转换成字符串类型
# 编码
s = '天涯共此时'
print(s.encode(encoding='GBK')) # GBK编码格式中一个中文占两个字节
"""
结果为:
b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
# b表示二进制
"""
print(s.encode(encoding='UTF-8')) # UTF-8编码格式中一个中文占三个字节
"""
结果为:
b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
"""
# 解码
# byte代表一个二进制数据(字节类型的数据)
byte = s.encode(encoding='GBK') # 编码
print(byte.decode(encoding='GBK')) # 解码
# 编码解码的编码格式必须选择同一类型
byte = s.encode(encoding='UTF-8')
print(byte.decode(encoding='UTF-8'))