前言
Python 字符串适合保存和处理文本,元组适合把多个有顺序的值组合成一条固定记录。先掌握字符串的索引与方法,再用元组保存学生信息并完成解包、统计,就能看到这两种数据容器在实际代码中的分工。
一、Python 字符串的特点,再类比 Java String
Python 字符串有序、可迭代,而且创建后不能直接修改其中的字符:
python
s = "hello"
print(s[1])
print(s[::-1])
print(s[:3])
索引从 0 开始,所以 s[1] 得到 e。切片 s[::-1] 使用负步长反向取值,结果是 olleh;s[:3] 截取前三个字符,结束位置 3 不包含在结果中。
Java 的 String 同样不可变,也支持按索引读取字符:
java
String s = "hello";
System.out.println(s.charAt(1));
System.out.println(s.substring(0, 3));
两种语言都不会通过索引直接改写字符串中的字符。Python 的切片可以用负步长反转字符串;Java 通常使用 StringBuilder 的 reverse() 完成反转。
二、使用字符串方法查找和转换文本
字符串方法可以完成查找、统计、大小写转换、分割、去除两端字符和替换:
python
s = "Hello Python"
# find() 在字符串中查找子串,返回第一次出现的索引位置,找不到返回 -1
print(s.find('Python')) # 6
print(s.find('Java')) # -1
# count() 统计子串在字符串中出现的次数
print(s.count('H')) # 1
print(s.count('o')) # 2
# upper() 将字符串中的所有字母转换为大写
print(s.upper()) # HELLO PYTHON
# lower() 将字符串中的所有字母转换为小写
print(s.lower()) # hello python
# split() 将字符串按指定分隔符分割成列表
print(s.split(' ')) # ['Hello', 'Python']
# strip() 去除字符串两端的空白字符或指定字符
s2 = " Hello "
print(s2.strip()) # 'Hello'
s3 = "**Hello**"
print(s3.strip('*')) # 'Hello'
# replace() 将字符串中的指定子串替换为新的子串
print(s.replace('H', 'C')) # Cello Python
# startswith() 检查字符串是否以指定子串开头,返回布尔值
print(s.startswith('H')) # True
print(s.startswith('P')) # False
这些方法都会返回处理结果,不会直接改变原字符串。比如 upper() 返回大写后的新字符串,replace() 返回替换后的新字符串。
find() 找不到目标时返回 -1,与 Java String 的 indexOf() 行为相近。大小写转换、分割、替换和前缀判断也都有对应的 Java String 方法。Python 的 count() 可以直接统计子串出现次数;Java String 没有同名的直接方法。
要注意,strip('*') 会从字符串两端去除属于 * 的字符,不是把两端的 "*" 当作一个完整子串删除。它也不会删除字符串中间的字符。
三个字符串小需求
需求一:判断邮箱文本是否包含基本格式
python
email = input("请输入你的邮箱:")
if email.count("@") == 1 and "." in email:
print("合规")
else:
print("不合规")
这段代码检查文本中是否恰好有一个 @,以及是否包含 .。它适合练习字符串的计数和成员判断,只能做初步筛查,不能完整验证邮箱地址格式。
需求二:把输入的三个文本转为大写并保存
python
uppercase_values = []
for i in range(3):
value = input("请输入:")
uppercase_values.append(value.upper())
print(uppercase_values)
每次读取一个文本,upper() 返回对应的大写字符串,再由 append() 保存到列表。Java 中可以用 ArrayList<String> 保存多段文本,并调用 String 的大小写转换方法处理每个元素。
三、元组
元组和列表一样可以按顺序保存多个元素,但元组创建后不能替换、增加或删除其中的元素:
python
t1 = (1, 2, 3, 1)
t2 = ()
t3 = tuple(t1)
print(t1.count(1))
print(t1.index(1))
count(1) 返回元素 1 出现的次数,index(1) 返回它第一次出现的位置。元组可以有重复元素,也可以保存不同类型的值。
定义只含一个元素的元组时,逗号不能省略:
python
t = (1,)
a = 1,
print(type(t))
print(type(a))
括号不是单元素元组成立的关键,逗号才是。(1) 只是整数表达式,(1,) 才是单元素元组。
四、使用元组打包、解包和交换变量
多个值可以组成元组,再按顺序解包到多个变量中:
python
t1 = (1, 2, 3, 4)
a, b, c, d = t1
print(a)
左侧变量数量必须与元组元素数量一致。星号可以接收剩余元素,接收结果会是一个列表:
python
t2 = (5, 7, 8, 4)
x, *y, z = t2 # x=5, y=[7, 8], z=4
i, *j = t2 # i=5, j=[7, 8, 4]
*o, p = t2 # o=[5, 7, 8], p=4
Python 还可以用打包和解包交换变量:
python
a = 1
b = 2
a, b = b, a
print(a, b)
i, j, k = 4, 5, 6
i, j, k = k, j, i
print(i, j, k)
赋值右侧先组成一组值,再依次赋给左侧变量。Java 没有这种多变量解包语法,交换两个变量时通常借助临时变量。
需求三:用元组保存学生信息并统计成绩
学生记录由学号、姓名和三门成绩组成。将每位学生的信息放入元组,再把所有学生记录放入外层元组,可以保留数据顺序并避免意外替换记录中的元素。
python
stu = (
("S001", "王林", 85, 92, 78),
("S002", "李慕婉", 92, 88, 95),
("S003", "十三", 78, 85, 82),
("S004", "曾牛", 88, 79, 91),
("S005", "周铁", 95, 96, 89),
("S006", "王卓", 76, 82, 77),
("S007", "红蝶", 89, 91, 94),
("S008", "徐立国", 75, 69, 82),
("S009", "许木", 86, 89, 98),
("S010", "遁天", 66, 59, 72)
)
for student_id, name, chinese, math, english in stu:
total = chinese + math + english
avg = total / 3
print(f"{student_id} {name} {chinese} {math} {english} {total} {avg:.1f}")
循环每次取出一条学生记录,并将五个位置依次解包到变量中:学号、姓名、语文、数学和英语。总分由三科成绩相加得到,平均分由总分除以 3 得到;格式说明 .1f 将平均分显示为一位小数。
还可以按成绩所在位置提取各科数据,再计算最低分、最高分和平均分:
python
subject_names = ("语文", "数学", "英语")
for index, subject_name in enumerate(subject_names, start=2):
scores = [student[index] for student in stu]
avg = sum(scores) / len(scores)
print(
f"{subject_name}最低分:{min(scores)},"
f"最高分:{max(scores)},平均分:{avg:.1f}"
)
学号和姓名分别位于索引 0 和 1,三门成绩从索引 2 开始,所以 enumerate(..., start=2) 可以让科目名称与成绩位置对应。列表推导式从每条学生记录中取出当前科目的成绩,随后用 min()、max()、sum() 和 len() 完成统计。
总结
字符串适合处理不可变文本,元组适合保存顺序固定的数据记录;解包可以让按位置保存的数据更容易参与计算。类比 Java 时,Python 字符串与 Java String 都不可变,元组则不能直接等同于 Java 数组:数组位置可修改,元组记录本身不可替换。