一、字符串定义
1、字面量形式
# 1. 通过字符串字面量进行定义
# 把需要存储的若干字符,写到一对引号中
s1 = "hello world"
s2 = 'hello world'
2、str()
# 2. 通过函数 str() 将其他类型的数据,转成字符串
s3 = str(123)
s4 = str(3.14)
s5 = str("hello world")
3、字符串运算符
运算符 | 描述 | 示例 | |
算术运算符 | + | 将两个字符串拼接 | "hello" + "world" |
算术运算符 | * | 将字符串重复若干次 | "-*" * 30 |
算术运算符 | += | 在现有值的基础上拼接 | s1 = "hello" s1 += "world" |
算术运算符 | *= | 在现有值的基础上重复 | s1 = "-*" s1 *= 30 |
算术运算符 | % | 字符串格式化 | "|%d|%.2f|%s|" % (10, 3.1415,"hello") |
关系运算符 | == | 判断两个字符串是否相同 | "hello" == "hello" |
关系运算符 | != | 判断两个字符串是否不同 | "hello" != "hello" |
关系运算符 | > | 判断字符串大小关系 | "hello" > "ha" |
关系运算符 | < | 判断字符串大小关系 | "hello" < "ha" |
关系运算符 | >= | 判断字符串大小关系 | "hello" >= "ha" |
关系运算符 | <= | 判断字符串大小关系 | "hello" <= "ha" |
包含关系 | in | 判断一个字符串是否在另外一个字符串中包含 | "ha" in "hadoop" |
包含关系 | not in | 判断一个字符串是否不在另外一个字符串中包含 | "ha" not in "hadoop" |
# 可以使用某些运算符,去操作两个字符串
# +: 拼接两个字符串,但是需要注意,只能完成字符串与字符串的拼接
print("hello" + "world")
# *: 将某一个字符串重复若干次,生成一个新的字符串
print("-*" * 20)
# %: 字符串格式化
# %f、%d、%s
# %o: 将一个十进制的数字,转成八进制表示
# %x: 将一个十进制的数字,转成十六进制表示
# %#: 格式化进制表示形式
print("|%o|%x|%X|" % (200, 200, 200))
print("|%08o|%08x|%08X|" % (200, 200, 200))
print("|%#08o|%#08x|%#08X|" % (200, 200, 200))
# +=
s1 = "hello"
s1 += "world"
print(s1)
# *=
s2 = "-*"
s2 *= 10
print(s2)
# > < >= <= == !=
# 关系运算:两个字符串也是可以比较大小的
# 比较规则:
# - 比较首位字符的大小(通过字符集中的对应的数字来比较)
# - 如果可以区分大小: 停止继续比较了,以本次的大小,作为字符串的大小比较结果
# - 如果无法区分大小: 继续比较后面一位字符
print("hello" > "horld")
print("hadoop" > "he")
print("hello" > "he")
# 需求: 从控制台输入一个字符,判断是否是小写字母
# letter = input()
# print("a" <= letter <= "z")
# in
# 判断一个字符串,是否在另外的一个字符串中包含
print("he" in "hello")
print("hl" in "hello")
二、字符串索引
1、索引的概念
每一个元素,在容器中存储的时候都会有一个位置信息,这个位置信息称为“索引”,也叫做“下标”。
在字符串中,就是表示某一个字符在字符串中的位置信息。
2、索引的分类
正向索引:从0开始,使用正数表示元素的位置索引信息,从前往后的。范围 [0, 长度-1]
负向索引:从-1开始,使用负数表示元素的位置索引信息,从后往前的。范围 [-1, -长度]
3、索引的使用
通过索引,可以按照指定的位置,获取对应位的元素。在使用的时候,将索引的值写入到一对 [] 中。
# 索引: 元素在容器中存在的位置,又称为”下标“
# 注意事项: 索引是从 0 开始的!
#
# 正向索引: 从0开始,使用正数表示元素的位置索引信息,从前往后的。范围 [0, 长度-1]
# 负向索引: 从-1开始,使用负数表示元素的位置索引信息,从后往前的。范围 [-1, -长度]
#
# 可以通过索引,获取到指定位置的元素,使用的语法是 []
# 使用索引的时候,一定不要越界!如果越界,就会出现IndexError
s1 = "hello world"
print(s1[0]) # h
print(s1[6]) # w
print(s1[10]) # d
# print(s1[11]) # IndexError
print(s1[-1]) # d
print(s1[-4]) # o
print(s1[-11]) # h
# print(s1[-12]) # IndexError
# 字符串是不可变的,因此我们可以通过索引找到指定位的元素是谁,但是,不能修改!
# s1[0] = "W"
# 需求: 通过一个元素,查找他的位置索引(只考虑第一次出现的位置即可)
# len: 获取字符串的长度
print(len(s1))
def index_of(s1, c1):
i = 0
for c in s1:
if c1 == c:
return i
i += 1
print(index_of("hello world", "l"))
注意事项
使用索引的时候,一定不要越界,否则会出现 IndexError。
三、字符串切片
1、切片是做什么的
获取一个容器中的一部分数据的。
与索引不同,通过索引只能够获取到一位元素,但是切片可以获取多个。
2、切片的使用
语法: [起始索引:结束索引:步长],获取 [起始索引, 结束索引)
- 起始索引: 从第几位开始获取
- 结束索引: 到第几位结束
- 步长: 获取指定范围内的元素的步长,默认是1,表示连续获取到的两个元素之间的索引差值
默认值:
- 起始索引:
-
- 如果是正向切片(步长为正数),起始索引是容器的最左边开始
- 如果是负向切片(步长为负数),起始索引是容器的最右边开始
- 结束索引:
-
- 如果是正向切片(步长为正数),结束索引是容器的最右边结束
- 如果是负向切片(步长为负数),结束索引是容器的最左边结束
s1 = "hello world"
print(s1[2:7])
print(s1[:7]) # 省略掉了起始索引,默认从0开始的
print(s1[7:]) # 省略掉了结束索引,默认是到 len(s1)
print(s1[:]) # 省略掉了起始索引,默认从0开始的,省略掉了结束索引,默认是到 len(s1)
print(s1[-4:-1]) # 也可以使用负数的索引
print(s1[2:-2])
print(s1[2:7:2])
print(s1[7:2:-1])
print(s1[::-1]) # dlrow olleh
print(s1[7::-1]) # ow olleh
print(s1[:3:-1]) # dlrow o
# 判断一个数字是不是回文数
number = 12345
reverse_number = str(number)[::-1]
print(reverse_number)
四、字符串遍历
# 遍历: 依次获取到一个容器中的每一个元素
s = "hello world"
# 1. 使用for循环,依次获取到每一个元素
for c in s:
print(c)
# 2. 使用for循环,依次获取到每一个下标
# 下标遍历法(索引遍历)
for i in range(len(s)):
print(s[i])
# 3. 既需要下标,又需要元素
# enumerate(s)可以给我们生成一个二元组,其实就是一个元组,其中的元素也是元组类型
# 这个二元组其中的元素数量是固定2位,第0位表示下标,第1位表示字符
for index, value in enumerate(s):
print(index, value)
字符串获取操作
函数 | 意义 | 示例 |
index(_sub, _start, _end) | 在指定范围内查找 _sub 子串的下标 _start 默认是字符串的开头 _end 默认是字符串的结尾 注意事项:如果找不到,会异常 | print(s.index("qf")) print(s.index("qf", 3)) print(s.index("qf", 3, 10)) |
find(_sub, _start, _end) | 在指定范围内查找 _sub 子串的下标 _start 默认是字符串的开头 _end 默认是字符串的结尾 注意事项:如果找不到,会返回-1 | print(s.find("qf")) print(s.find("qf"), 3) print(s.find("qf"), 3, 10) |
rindex(_sub, _start, _end) | 在指定范围内查找 _sub 子串的最后一次出现的下标 _start 默认是字符串的开头 _end 默认是字符串的结尾 注意事项:如果找不到,会异常 | print(s.rindex("qf")) print(s.rindex("qf", 3)) print(s.rindex("qf", 3, 10)) |
rfind(_sub, _start, _end) | 在指定范围内查找 _sub 子串的最后一次出现的下标 _start 默认是字符串的开头 _end 默认是字符串的结尾 注意事项:如果找不到,会返回-1 | print(s.find("qf")) print(s.find("qf"), 3) print(s.find("qf"), 3, 10) |
count(_sub, _start, _end) | 在指定范围内查找 _sub 子串出现的次数 _start 默认是字符串的开头 _end 默认是字符串的结尾 | print(s.count("a")) print(s.count("a", 3)) print(s.count("a", 3, 10)) |
s = "Welcome to qf study bigdata"
'''
1. 在指定范围中 查询子串第一次出现的位置
字符串对象.index(子串, 起始位置, 结束位置) --- 找不到报错
字符串对象.find(子串, 起始位置, 结束位置) --- 找不到 返回的是-1
子串是多个字符 获取的是首字符的下标
'''
# print(s.index("qf"))
print(s.find("qf"))
'''
2. 在指定范围中 查询子串最后一次出现的位置
字符串对象.rindex(子串, 起始位置, 结束位置) --- 找不到报错
字符串对象.rfind(子串, 起始位置, 结束位置) --- 找不到 返回的是-1
子串是多个符号 获取的是第一个符号的下标
'''
# print(s.rindex("o", 6, 8))
# print(s.rfind("o"))
'''
3. 在指定范围中 查询子串出现的次数
字符串对象.count(子串, 起始位置, 结束位置)
'''
print(s.count("a"))
print(s.count("a", -4))
print(s.count("a", -4, -2))
字符串转换操作
函数 | 意义 | 示例 |
upper() | 将一个字符串中的小写字母转成大写 | s.upper() |
lower() | 将一个字符串中的大写字母转成小写 | s.lower() |
swapcase() | 将一个字符串中的大小写字母翻转 | s.swapcase() |
capitalize | 将一个字符串的首字母变成大写,其他字母小写 | s.capitalize() |
title | 将一个字符串的每一个单词的首字母变大写,其他字母小写 | s.title() |
encode(encoding) | 将一个字符串转成一个指定字符集的字节序列 | s.encode(encoding="utf8") |
decode(encoding) | 注意,这个函数并不是str的函数,需要使用一个字节序列来调用。将一个字节序列,按照指定的字符集,解析成为一个字符串 | binary_str.decode(encoding="utf8") |
s = 'helLo, Nice to Meet you. My age is 18. ahekl1fnfsd hjdhsjhgfs'
# 1. 将小写英文字母转化为大写 其他的不变
print(s.upper())
# 2. 将大写英文字母转化为小写 其他的不变
print(s.lower())
# 3. 大写转小写 小写转大写 其他字符不变
print(s.swapcase())
# 4. 首字母大写 其他字母小写 其他符号不变
print(s.capitalize())
# 5. 每个单词首字母大写 其他小写
# 单词: 非连续性的符号组在一起就是单词
print(s.title())
s = 'abc1234你好'
# 6. 按照GBK的编码规则 获取字符对应的字节数据
binary_data = s.encode(encoding="utf8")
for b in binary_data:
print(b)
# 7. 将一个字节序列,按照指定的字符集,转成字符串
print(binary_data.decode(encoding="gbk"))
字符串的判断操作
函数 | 意义 | 示例 |
isdigit() | 判断一个字符串是否是纯数字 | "123".isdigit() |
isalpha() | 判断一个字符串是否是纯字母 注意事项:并非只是英文字母,其他的文字,例如中文中的每一个汉字,也都被视为字母 | "abc".isalpha() |
isalnum() | 判断字符串的内容是否为数字或者字母 | "123abc".isalnum() |
isupper() | 判断字符串中的英文字母是否为大写字母 | "123abc".isupper() |
islower() | 判断字符串中的英文字母是否为小写字母 | "123abc".islower() |
istitle() | 判断字符串的内容是否满足 单词的首字母大写 其他小写 | "Hello World".istitle() |
startswith() | 判断字符串是否以指定的字符串开头 参数可以是一个字符串,也可以是一个元组 字符串参数:判断是否是以指定字符串开头 元组参数:判断是否是以元组中的任意一个字符串开头 | "Harry Potter".startswith("Harry") "Harry Potter".startswith(("Harry", "harry", "HARRY")) |
endwith() | 判断字符串是否以指定的字符串结尾 参数可以是一个字符串,也可以是一个元组 字符串参数:判断是否是以指定的字符串结尾 元组参数:判断是否是以元组中的任意一个字符串结尾 | "Harry Potter.mp4".endswith(".mp4") "Harry Potter.mp4".endswith((".mp4", ".rmvb", ".avi")) |
字符串的格式化操作
函数 | 意义 | 示例 |
ljust(_width, _fillchar) | 按照指定的宽度,对字符串的内容进行填充,居左对齐 _width: 宽度 _fillchar: 向右填充的字符,默认空格 | 'hello'.ljust(10) 'hello'.ljust(10, '-') |
rjust(_width, _fillchar) | 按照指定的宽度,对字符串的内容进行填充,居右对齐 _width: 宽度 _fillchar: 向左填充的字符,默认空格 | 'hello'.rjust(10) 'hello'.rjust(10, '-') |
center(_width, _fillchar) | 按照指定的宽度,对字符串的内容进行填充,居右对齐 _width: 宽度 _fillchar: 向左填充的字符,默认空格 | 'hello'.center(10) 'hello'.center(10, '-') |
zfill(_width) | 按照指定的宽度,对字符串的内容进行填充,居右对齐,左侧填充 0 _width: 宽度 | '10'.zfill(10) |
# ljust : 填充字符串,居左对齐,需要向右填充到指定的宽度
# rjust : 填充字符串,居右对齐,需要向左填充到指定的宽度
# center: 填充字符串,居中对齐,需要向两端填充到指定的宽度
# _width: 需要填充到的宽度
# _fillchar: 需要使用什么字符填充,默认是空格
# zfill : 类似与rjust,只需要设置一个宽度,不能设置填充字符,自己以0填充
print("hello".ljust(10))
print("hello".ljust(10, "-"))
print("hello".rjust(10))
print("hello".rjust(10, "-"))
print("hello".center(10))
print("hello".center(10, "-"))
print("10".zfill(8))
字符串快速格式化(1)
# 概念
# 所谓的“字符串格式化”,就是将多个变量便捷的拼接到一个字符串中
# 比起字符串的直接拼接操作,格式化操作可以快速、方便的实现多个变量在一个字符串中的快速融合,并且可以按照指定的格式融合
#
# 字符串格式化有几种方式:
# 1. % 运算符
# 这种方式的字符串格式化,有点类似于 C、Java 等语言中的格式化操作
# 使用 %s、%f、%d 等占位符,表示对一个变量在一个完整字符串中的占位
# %s: 对一个字符串类型(str)的变量的占位
# %d: 对一个整型(int)的变量的占位
# %f: 对一个浮点型(float)的变量的占位
name: str = "Tom"
age: int = 18
height: float = 177.34
message_01 = "My name is %s, I'm %d years old now, and my height is %fcm" % (name, age, height)
print(message_01)
# 在使用以上的几种占位符的时候,还有一些特殊的操作,可以对变量的值进行指定格式的融合
# %s:
# %ns: 表示一个指定字符宽度的占位
# %10s,表示需要一个宽度为 10 的字符串,不够 10 位的部分,向左补空格
# %-10s,表示需要一个宽度为 10 的字符串,不够 10 位的部分,向右补空格
message_02 = "|%10s|%-10s|" % ("Tom", "Jerry")
print(message_02)
# %d:
# %0nd: 表示一个指定字符宽度的占位
# %010d,表示需要一个宽度为 10 的字符串,不够 10 的部分,向左补 0
# %nd: 表示一个指定字符宽度的占位
# %10d,表示需要一个宽度为 10 的字符串,不够 10 的部分,向左补空格
# %-10d,表示需要一个宽度为 10 的字符串,不够 10 的部分,向右补空格
message_03 = "|%010d|%10d|%-10d|" % (10, 10, 10)
print(message_03)
# %f:
# %.nf: 表示小数点后面的精度
# %.2f,表示小数点后面保留 2 位精度,取四舍五入
# %m.nf: 表示一个指定字符宽度的占位
# m: 表示需要的宽度,包含小数点和小数点后面的位数
# n: 表示小数点的精度
# %10.2f,表示需要一个宽度为 10 的字符串,小数点后面精度保留两位,不够 10 位的部分,向左补空格
# %010.2f,表示需要一个宽度为 10 的字符串,小数点后面精度保留两位,不够 10 位的部分,向左补 0
message_04 = "|%.2f|%10.2f|%010.2f|" % (3.141592653, 3.141592653, 3.141592653)
print(message_04)
# %o: 表示将一个十进制的数字,格式化为八进制的表示形式
# %no: 表示一个指定宽度的字符串
# %8o,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向左补空格
# %-8o,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向右补空格
# %08o,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向左补 0
# %#o: 表示需要一个带有 0o 标识的字符串
message_05 = "|%o|%8o|%-8o|%08o|%#08o|" % (10, 10, 10, 10, 10)
print(message_05)
# %x: 表示将一个十进制的数字,格式化为十六进制的表示形式
# %nx: 表示一个指定宽度的字符串
# %8x,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向左补空格
# %-8x,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向右补空格
# %08x,表示需要一个宽度为 8 的字符串,不够 8 位的部分,向左补 0
# 小写字母x表示需要将十六进制中的a~f的部分,用小写字母表示
# 大写字母X表示需要将十六进制中的A-F的部分,用大写字母表示
# %#x: 表示需要一个带有 0x 标识的字符串
message_06 = "|%x|%8x|%-8x|%08x|%#08x|" % (100, 100, 100, 100, 100)
print(message_06)
字符串快速格式化(2)
# 2. f 格式化
# 在字符串的引号前方添加字符 f,可以对字符串进行快速格式化
# 与 % 不同,f 字符串不需要在字符串中添加 % 的占位符,直接将需要融合进来的变量,写在一对 {} 中即可
name = "Tom"
age = 19
height = 173.55
message_07 = f"My name is {name}, I'm {age} years old, and I have {height}cm high"
print(message_07)
# {} 中不仅仅可以使用变量,也可以使用表达式
n1 = 10
n2 = 20
message_08 = f"{n1} + {n2} = {n1 + n2}"
print(message_08)
# {} 中可以使用 % 中的宽度修饰符
year = 2023
month = 9
day = 3
temperature = 37.5
message_09 = f"Today is {year}-{month:02d}-{day:02d}, temperature is {temperature:.2f}℃"
print(message_09)
# {} 还可以有自己独有的,更加简单的宽度修饰符,在 : 后面使用如下的修饰符
# < 表示居左对齐 ^ 表示居中对齐 > 表示居右对齐
# 使用方式: m<n
# 其中m表示填充的字符,如果不设置,默认使用空格填充
# n表示需要的宽度
# 0<5: 表示需要宽度为 5 的字符串,不够的部分向右填充 0
# -^8: 表示需要宽度为 8 的字符串,不够的部分向两端填充 -
# 0>7: 表示需要宽度为 7 的字符串,不够的部分向左填充 0
message_10 = f"|{10:0<10}|{10:-^10}|{10:0>10}|"
print(message_10)
# : 之后还可以有一些其他的修饰符
# :b 表示需要转成二进制表示形式
# :o 表示需要转成八进制表示形式
# :x 表示需要转成十六进制表示形式,小写x表示a-f的部分使用小写,大写X表示A-F部分使用大写
# 以上的进制表示形式,都可以使用#表示添加标识符
#
# :e 表示需要使用科学计数法表示形式
# :, 表示需要使用千位分隔表示形式
message_11 = f"|{170:#010b}|{170:#o}|{170:#x}|{1900000000:e}|{1234567890:,}|"
print(message_11)
# 如果宽度的值也是一个变量,那么可以在{}内再嵌套{}
value = 170
width = 10
message_12 = f"|{value:#{width}b}|"
print(message_12)
字符串的切割与拼接
函数 | 说明 | 示例 |
split(__sep, __maxsplit) | 将字符串,从左往右,按照指定的分隔符进行切割 __sep: 指定的分隔符,默认是若干空格 __maxsplit: 切割的次数,默认是不限制次数 | "Lily Lucy Tom".split(" ") "Lily Lucy Tom".split() "Lily,Lucy,Tom".split(",") "Lily,Lucy,Tom".split(",", 1) |
rsplit(__sep, __maxsplit) | 将字符串,从右往左,按照指定的分隔符进行切割 __sep: 指定的分隔符,默认是若干空格 __maxsplit: 切割的次数,默认是不限制次数 | "Lily Lucy Tom".rsplit(" ") "Lily Lucy Tom".rsplit() "Lily,Lucy,Tom".rsplit(",") "Lily,Lucy,Tom".rsplit(",", 1) |
join(__iterable) | 将一个容器中的若干元素,按照指定的分隔符拼接到一起 __iterable: 可以迭代的容器,包含str, list, tuple | ",".join(["Tom", "Jerry", "Li"]) |
# 切割: 以指定子串为切割点 将字符串分成n段
# split(sep, maxsplit): 将一个字符串,按照sep进行切割
# sep: 切割的依据,默认是若干空白
# maxsplit: 切割的次数,默认是-1
# 返回值是一个容器,可以使用下标(索引)访问到每一个元素
s1 = "Lily Lucy Tom Jerry Maria Nancy"
# 需求: 得到每一个名字
print(s1.split(" "))
print("Lily,Lucy,Tom,Jerry,Maria,Nancy".split(","))
print("Lily,Lucy,Tom,Jerry,Maria,Nancy".split(",", maxsplit=3))
res = "Lily Lucy Tom Jerry Maria Nancy".split()
print(res[3])
# rsplit(sep, maxsplit): 从后往前切
print("Lily Lucy Tom Jerry Maria Nancy".rsplit(maxsplit=1))
# 拼接 join
# 使用方式: 使用一个分隔符,调用join函数,参数部分传递的是一个数据容器,容器中的元素,需要都是字符串类型
print(", ".join(("Lily", "lucy", "Uncle Wang")))
字符串打的替换和移除操作
函数 | 描述 | 示例 |
replace(__old, __new, __count) | 将一个字符串中指定的字符串,替换成新的字符串。 __old: 需要被替换的字符串 __new: 需要替换到的新的字符串 __count: 替换的次数 | "hello world".replace("l", "L") "hello world".replace("l", "L", 1) |
strip(__chars) | 去除一个字符串左右两端的指定字符,默认去除空格 | " hello ".strip() "----hello----".strip("-") |
lstrip(__chars) | 去除一个字符串左边的指定字符,默认去除空格 | " hello ".lstrip() "----hello----".lstrip("-") |
rstrip(__chars) | 去除一个字符串右边的指定字符,默认去除空格 | " hello ".rstrip() "----hello----".rstrip("-") |
# replace(__old, __new, __count):
# 函数意义: 使用 __new 字符串,替换原来字符串中的 __old 部分
# __old: 需要被替换的部分
# __new: 需要替换上的部分
# __count: 需要替换的次数,如果不设置这个参数,代表全部替换
print("hello world".replace("l", "L"))
print("hello world".replace("l", "L", 2))
print("hello world".replace("ll", "LL", 2))
# strip(__chars)
# 函数意义: 去除一个字符串左右两端的指定字符,默认去除空格
# __chars: 需要去除的字符是谁,默认是空格
print(" hello world ".strip())
print("-----hello world-----".strip("-"))
# lstrip(): 去除一个字符串左边的指定字符,默认去除空格
# rstrip(): 去除一个字符串右边的指定字符,默认去除空格
print("-----hello world-----".lstrip("-"))
print("-----hello world-----".rstrip("-"))