python源码中的学习笔记_第7章_字符串

字符串的驻留机制

#
# 主题:字符串的驻留机制
#

if __name__ == '__main__':
    # 不可变序列:元组、字符串

    # 驻留机制:
    # 对于相同的字符串,只保留一份拷贝,
    # 后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
    a = 'python'
    b = "python"
    c = '''python'''
    print(id(a))            # 1430903362144
    print(id(b))            # 1430903362144
    print(id(c))            # 1430903362144

    # 驻留机制的前提条件
    # 驻留机制在 python 原编译器中会出现,而在后续的集成环境中,如 PyCharm,就不会发生
    # PyCharm 对字符串进行了优化
    # 可以在命令行中输入 python 并回车,进入交互式 python,之后输入下列代码验证
    # 1. 字符串的长度为 0 或 1
    a = 'a'
    b = 'a'
    print(id(a))            # 1610197355576
    print(id(b))            # 1610197355576
                            # 符合驻留机制的条件

    # 2. 符合标识符的字符串,即字符串中只有数字、字母、下划线

    # 3. 字符串只在编译时进行驻留,而不是运行时
    a = 'abc'
    b = 'ab' + 'c'              # 在编译时连接字符串
    c = ''.join(['ab', 'c'])    # 在运行时,调用 join 方法,然后连接字符串
    print(a is b)               # 符合驻留条件
    print(a is c)               # 不符合驻留条件

    # 4. [-5, 256] 之间的整数数字也可发生驻留

    # sys 包中的 intern 方法强制两个字符串指向同一个对象
    import sys
    a = 'ab%'
    b = 'ab%'
    print(a is b)               # False
    a = sys.intern(b)
    print(a is b)               # True
    
    # 字符串驻留机制的优点
    # 优点:
    # 当需要值相等的字符串时,可以直接从字符串池里拿来使用,避免频繁地创建和校徽,提升效率和节约内存
    
    # 注意
    # 拼接、修改字符串是比较影响性能的
    # 拼接字符串时,建议使用字符串的 join 方法,而不是 + 
    # join 方法先计算出所有字符串的长度,然后拷贝。这样,就 new 一次对象,效率比 + 高

字符串的查询操作的方法

#
# 主题:字符串的查询操作的方法
#

if __name__ == '__main__':
    s = 'hello, hello'

    # index 方法
    # 查找子字符串第一次出现的位置,若不存在,则报错 ValueError
    print(s.index('lo'))        # 3

    # find 方法
    # 查找子字符串第一次出现的位置,若不存在,则返回 -1
    print(s.find('lo'))         # 3

    # rindex 方法
    # 查找子字符串最后一次出现的位置,若不存在,则报错 ValueError
    print(s.rindex('lo'))       # 10

    # rfind 方法
    # 查找子字符串最后一次出现的位置,若不存在,则返回 -1
    print(s.rfind('lo'))        # 10

    # 推荐使用 find 方法和 rfind 方法

字符串的大小写转换

#
# 主题:字符串的大小写转换
#

if __name__ == '__main__':
    s = 'hello, python'
    s1 = 'Hello, Python'

    # 字符串中所有字符都转成大写字母
    a = s.upper()
    print(s, id(s))             # hello, python 2250561907376
    print(a, id(a))             # HELLO, PYTHON 2250561907312
    # upper 方法生成新对象

    # 字符串中所有字符都转成小写字母
    b = a.lower()
    print(a, id(a))             # HELLO, PYTHON 3022125492656
    print(b, id(b))             # hello, python 3022125492784
    # lower 方法生成新对象

    # 字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母
    c = s1.swapcase()
    print(s1, id(s1))           # Hello, Python 1664029387440
    print(c, id(c))             # hELLO, pYTHON 1664029434800
    # swapcase 方法生成新对象

    # 第一个字符转为大写,其余字符转换为小写
    d = s.capitalize()
    print(s, id(s))             # hello, python 2055284947312
    print(d, id(d))             # Hello, python 2055284990704
    # capitalize 方法生成新对象

    # 字符串中每个单词的第一个字符都转为大写,其余字符都转为小写
    e = s.title()
    print(s, id(s))             # hello, python 2003960162928
    print(e, id(e))             # Hello, Python 2003960210480

字符串内容对齐

#
# 主题:字符串内容对齐
#

if __name__ == '__main__':
    s = 'hello, python'

    # 居中对齐
    # 第1个参数指定宽度,第2个参数指定填充符,第2个参数可选,默认是空格,若设置宽度小于实际宽度则返回原字符串
    print(s.center(20, '*'))            # ***hello, python****
    print(s.center(20))                 #    hello, python
    print(s.center(10, '#'))            # hello, python 返回原字符串

    # 左对齐
    # 第1个参数指定宽度,第2个参数指定填充符,第2个参数可选,默认是空格,若设置宽度小于实际宽度则返回原字符串
    print(s.ljust(20, '*'))             # hello, python*******
    print(s.ljust(20))                  # hello, python
    print(s.ljust(10))                  # hello, python 返回原字符串

    # 右对齐
    # 第1个参数指定宽度,第2个参数指定填充符,第2个参数可选,默认是空格,若设置宽度小于实际宽度则返回原字符串
    print(s.rjust(20, '*'))             # *******hello, python
    print(s.rjust(20))                  #        hello, python
    print(s.rjust(10))                  # hello, python 返回原字符串

    # 右对齐
    # 左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,若指定的宽度小于字符串的长度,返回字符串本身
    print(s.zfill(20))                  # 0000000hello, python
    print(s.zfill(10))                  # hello, python 返回原字符串

    s1 = '-800'
    print(s1.zfill(10))                 # -000000800

字符串劈分(分割)操作

#
# 主题:字符串劈分(分割)操作
#

if __name__ == '__main__':
    s = 'hello world python'

    # 从字符串左边开始分割,默认的分割字符是空格字符串,返回的结果的类型是 list
    # 通过参数 sep 指定分割字符串的字符
    # 通过参数 maxsplit 指定分割字符串时最大的分割次数,在经过最大次分割之后,剩余的子串会单独作为一部分
    lst = s.split()             # 默认以空格分割
    print(lst)                  # ['hello', 'world', 'python']

    print(s.split(sep = 'o'))   # ['hell', ' w', 'rld pyth', 'n']

    print(s.split(sep = 'o', maxsplit = 2)) # ['hell', ' w', 'rld python']

    # 从字符串右边开始分割,默认的分割字符是空格字符串,返回的结果的类型是 list
    # 通过参数 sep 指定分割字符串的字符
    # 通过参数 maxsplit 指定分割字符串时最大的分割次数,在经过最大次分割之后,剩余的子串会单独作为一部分
    lst = s.rsplit()  # 默认以空格分割
    print(lst)                  # ['hello', 'world', 'python']

    print(s.rsplit(sep='o'))    # ['hell', ' w', 'rld pyth', 'n']

    print(s.rsplit(sep='o', maxsplit=2))  # ['hello w', 'rld pyth', 'n']

字符串的判断操作

#
# 主题:字符串的判断操作
#

if __name__ == '__main__':
    s = 'hello, python'

    # 判断字符串是否为合法标识符
    print('1', s.isidentifier())       # False
                                        # isidentifier 方法判断是否为合法标识符
                                        # 合法标识符相关规定详见第1章
    print('2', '张三'.isidentifier())    # True

    # 判断字符串是否全部由空白字符(如回车、换行、水平制表符)组成
    print('3', '\t'.isspace())         # True

    # 判断字符串是否全部由字母组成
    print('4', 'hello'.isalpha())       # True
    print('5', 'hello,'.isalpha())      # False
    print('6', 'hello张三'.isalpha())    # True

    # 判断字符串是否全部由十进制数字组成
    print('7', '123'.isdecimal())       # True
    print('8', '123四'.isdecimal())      # False
    print('9', 'ⅠⅡⅢ'.isdecimal())       # False

    # 判断字符串是否全部由数字组成
    print('10', '123'.isnumeric())      # True
    print('11', '123四'.isnumeric())     # True
    print('12', 'ⅠⅡⅢ'.isnumeric())      # True

    # 判断字符串是否全部由字母和数字组成
    print('13', 'abc1'.isalnum())       # True
    print('14', '张三123'.isalnum())      # True
    print('15', 'abc!'.isalnum())       # False

字符串的替换和合并

#
# 主题:字符串的替换和合并
#

if __name__ == '__main__':
    s = 'hello,python,python,python'

    # 替换字符串
    # 第1个参数指定被替换的子字符串,第2个参数指定替换子字符串的字符串,第3个参数指定最大替换次数(可选)
    # 返回替换后得到的字符串,替换前的字符串不发生变化
    s1 = s.replace('python', 'java')
    s2 = s.replace('python', 'java', 2)
    print(s1, id(s1))          # hello,java,java,java 2958341037272
    print(s, id(s))             # hello,python,python,python 2958340910016
    print(s2)                   # hello,java,java,python
    # replace 方法返回新对象

    # 合并字符串
    # 将列表或元组中的字符串合并为一个字符串
    # join 方法返回新对象
    lst = ['hello', 'java', 'python']
    out = '|'.join(lst)
    print(lst, id(lst))         # ['hello', 'java', 'python'] 2537298027080
    print(out, id(out))         # hello|java|python 2537305168464

    t =  ('hello', 'java', 'python')
    print(''.join(t))           # hellojavapython
    print('*'.join('python'))   # p*y*t*h*o*n

字符串的比较

#
# 主题:字符串的比较
#

if __name__ == '__main__':
    # 用到的运算符:>, >=, <, <=, ==, !=

    # 比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比下去,
    #         直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,其余字符不会继续比较

    # 比较原理:比较字符时,比较的是其原始值,调用 ord 方法可以得到指定字符的原始值
    #       调用 chr 方法可以得到原始值对应的字符

    print('apple' > 'app')              # True
    print('apple' > 'banana')           # False
    print(ord('a'), ord('b'))           # 97 98
    print(chr(97), chr(98))             # a b

    print(ord('杨'))                     # 26472
    print(chr(26472))                   # 杨

    # == 是判断是否值相等,is 是判断是否地址相等
    a = b = 'python'
    c = 'python'

    print(a == b)                       # True
    print(b == c)                       # True
    print(a is b)                       # True
    print(a is c)                       # True

字符串的切片操作

#
# 主题:字符串的切片操作
#

if __name__ == '__main__':
    # 字符串是不可变类型,故不具备增删改操作。切片操作产生新对象
    s = 'hello,python'
    s1 = s[:5]
    s2 = s[6:]
    s3 = '!'
    newStr = s1 + s3 + s2

    print(s1)               # hello
    print(s2)               # python
    print(newStr)           # hello!python

    # 完整写法 [start: end: step]
    print(s[0:5:1])         # hello
    print(s[::2])           # hlopto
    print(s[::-1])          # nohtyp,olleh
    print(s[-6::1])         # python

格式化字符串

#
# 主题:格式化字符串
#

if __name__ == '__main__':
    # % 作占位符
    # %s 对应字符串,%i 或 %d 对应整数,%f 对应浮点数
    name = '张三'
    age = 20
    print('我是%s,今年%d岁' % (name, age))           # 我是张三,今年20岁
    print('%10d' % 99)                              #         99 其中,10 表示宽度
    print('%f' % 3.1415926)                         # 3.141593
    print('%.3f' % 3.1415926)                       # 3.142 其中,.3 表示小数点后三位,即精度
    print('%10.3f' % 3.1415926)                     #      3.142

    # {} 作占位符
    print('我叫{0},今年{1}岁'.format(name, age))     # 我叫张三,今年20岁
    print('{0:.3}'.format(3.1415926))               # 3.14 其中,.3 表示的是一共是三位数
    print('{0:.3f}'.format(3.1415926))              # 3.142 其中,.3f 表示的是3位小数
    print('{:.3f}'.format(3.1415926))               # 3.142
    print('{:10.3f}'.format(3.1415926))             #      3.142 其中,10表示宽度
    # print('{1:10.3f}'.format(3.1415926))          # 冒号前面的是索引,对应的是format()中的元素

    # f-string 即,f'字符串' 格式
    print(f'我叫{name},今年{age}岁')                 # 我叫张三,今年20岁

字符串的编码转换

#
# 主题:字符串的编码转换
#

if __name__ == '__main__':
    # 编码:字符串转换为二进制数据(bytes)
    # 解码:bytes 类型的数据转换为字符串类型
    # 二进制数据用于数据传输

    s = '天涯共此时'

    # 编码
    print(s.encode(encoding = 'GBK'))           # b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
                                                # 在 GBK 编码方式中,一个中文占2个字节
    print(s.encode(encoding = 'utf-8'))         # b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
                                                # 在 utf-8 编码中,一个中文占3字节

    # 解码
    # byte 代表一个二进制数据(字节类数据)
    # GBK 编码得到的数据必须使用 GBK 解码,utf-8编码得到的数据必须使用 utf-8 解码
    byte = b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'
    byte1 = b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'
    print(byte.decode(encoding = 'GBK'))        # 天涯共此时
    print(byte1.decode(encoding = 'utf-8'))     # 天涯共此时

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值