1. Python的数据类型
1.1 基本数据类型
1.1.1 整数(Integer)-正数、负数或零:
# 基本整数运算
age = 18 # 定义一个表示年龄的整数
temperature = -5 # 定义一个表示温度的负数
count = 0 # 定义一个表示计数的零
# 大数字的可读性处理
population = 1_000_000_000 # 使用下划线分隔,提高可读性
print(f"世界人口约为:{population}人") # 输出:世界人口约为:1000000000人
# 不同进制的表示
binary = 0b1010 # 0b开头表示二进制数,等于十进制的10
hex_num = 0xFF # 0x开头表示十六进制数,等于十进制的255
print(f"二进制1010等于十进制:{binary}") # 输出:二进制1010等于十进制:10
1.1.2 浮点数(Float)-带小数点的数字,比如温度、身高、体重等:
# 日常生活中的浮点数
height = 1.75 # 身高1.75米
weight = 65.5 # 体重65.5公斤
temperature = 36.5 # 体温36.5度
# 科学计数法表示
light_speed = 3e8 # 光速:3 × 10^8 米/秒
atom_size = 1e-10 # 原子大小:1 × 10^-10 米
# 浮点数运算
pi = 3.14159
radius = 5
area = pi * radius * radius # 计算圆的面积
print(f"圆的面积是:{area}") # 输出:圆的面积是:78.53975
1.1.3 布尔值(Boolean)-True和False:
# 基本布尔值
is_sunny = True # 今天天气晴朗
is_raining = False # 今天没有下雨
# 比较运算
age = 18
can_vote = age >= 18 # 判断是否达到投票年龄
print(f"可以投票吗?{can_vote}") # 输出:可以投票吗?True
# 逻辑运算
# 逻辑运算符:and、or、not
# 逻辑运算符用于组合多个条件
# and:所有条件都为True时,结果为True
# or:只要有一个条件为True,结果为True
# not:对条件取反
has_ticket = True
has_id = True
can_enter = has_ticket and has_id # 需要同时满足两个条件
print(f"可以入场吗?{can_enter}") # 输出:可以入场吗?True
1.1.4 复数(complex)
a = complex(3, 4) # 等同于 3 + 4j
b = 1 + 2j
print(a) # (3+4j)
# 可以通过 .real 获取实部,通过 .imag 获取虚部系数:
print(a.real) # 输出 3.0(实部,返回浮点数)
print(a.imag) # 输出 4.0(虚部系数,返回浮点数)
# 复数支持加减乘除等基本运算:
print(a + b) # 输出 (4+6j)
print(a * b) # 输出 (-5+10j)
# 使用 abs() 可以获取复数的模(即到原点的距离):
print(abs(3 + 4j)) # 输出 5.0(计算 sqrt(3² + 4²))
1.2 序列类型
1.2.1 字符串(Str)-字符串就是文字,可以是中文、英文或任何其他文字:
# 基本字符串
name = "小明" # 使用双引号
greeting = '你好' # 使用单引号
print(f"{name}说:{greeting}") # 输出:小明说:你好
# 特殊字符处理
# 使用转义字符 \ 来表示特殊字符
message = "他说:\"Python很有趣!\"" # 使用转义字符
print(message) # 输出:他说:"Python很有趣!"
# 三引号字符串
#可以包含多行文本,保留所有的换行和空格
#适合编写文档字符串、多行文本等
long_text = """这是一个多行字符串,
可以直接包含换行符,
不需要使用特殊的转义字符。"""
print(long_text)
1.2.2 列表(list)
用方括号
[]表示,元素可修改,如[1, 2, 'a']列表是可变对象,可以随时增删改查
# 1.列表的创建与基本操作
# 创建一个装水果的列表
fruits = ["苹果", "香蕉", "橙子"]
print(fruits) # 输出整个列表:['苹果', '香蕉', '橙子']
# 查看列表中有多少个元素
print(len(fruits)) # 输出:3
# 2.通过索引访问元素
# 创建一个装水果的列表
fruits = ["苹果", "香蕉", "橙子"]
# 索引从0开始,依次访问每个水果
print(fruits[0]) # 输出第一个元素:苹果
print(fruits[1]) # 输出第二个元素:香蕉
print(fruits[2]) # 输出第三个元素:橙子
# 访问最后一个元素,可以用-1
print(fruits[-1]) # 输出最后一个元素:橙子
# 访问倒数第二个元素
print(fruits[-2]) # 输出倒数第二个元素:香蕉
# 访问不存在索引的元素会报错
# print(fruits[3]) # 报错:IndexError: list index out of range
# 3. 添加和插入元素
# 创建一个装水果的列表
fruits = ["苹果", "香蕉", "橙子"]
# 在列表末尾添加一个新水果
fruits.append("葡萄")
print(fruits) # 输出:['苹果', '香蕉', '橙子', '葡萄']
# append一次只能添加一个元素
fruits.append("西瓜", "柠檬") # 报错:TypeError: append() takes exactly one argument (2 given)
# 在指定位置插入一个水果,比如插到第2个位置(索引为1)
fruits.insert(1, "西瓜")
print(fruits) # 输出:['苹果', '西瓜', '香蕉', '橙子', '葡萄']
# 4. 删除元素
# 创建一个装水果的列表
fruits = ["苹果", "香蕉", "橙子"]
# 删除最后一个水果
last = fruits.pop()
print(last) # 输出被删除的水果:橙子
print(fruits) # 输出:['苹果', '香蕉']
# 删除指定位置的水果,比如删除第2个(索引为1)
removed = fruits.pop(1)
print(removed) # 输出被删除的水果:香蕉
print(fruits) # 输出:['苹果']
# 5. 修改元素
# 创建一个装水果的列表
fruits = ["苹果", "香蕉", "橙子"]
# 把第二个水果改成“柠檬”
fruits[1] = "柠檬"
print(fruits) # 输出:['苹果', '柠檬', '橙子']
# 6. 列表可以包含不同类型的数据
# 列表中可以放数字、字符串、布尔值等
mixed = [100, "hello", False]
print(mixed) # 输出:[100, 'hello', False]
# 7. 列表可以嵌套列表
# 创建一个嵌套列表,类似二维表格
matrix = [
[1, 2, 3],
[4, 5, 6]
]
# 访问第二行第三列的元素
print(matrix[1][2]) # 输出:6
# 8. 空列表
# 创建一个空列表
empty = []
print(len(empty)) # 输出:0
1.2.3 元组(tuple)
用圆括号
()表示,元素不可修改,如(1, 2, 'a')
# 1. 元组的创建与访问
# 创建一个元组,存放三种颜色
colors = ("红色", "绿色", "蓝色")
print(colors) # 输出:('红色', '绿色', '蓝色')
# 访问元组的元素,和列表一样
print(colors[0]) # 输出:红色
print(colors[-1]) # 输出:蓝色
# 2. 元组的不可变性
# 创建一个元组,存放三种颜色
colors = ("红色", "绿色", "蓝色")
# 尝试修改元组的内容会报错
colors[1] = "黄色" # 这一行会报错:TypeError: 'tuple' object does not support item assignment
# 元组中的列表内容可以修改
fruits = ("苹果", ["香蕉", "橙子"])
fruits[1][0] = "西瓜"
print(fruits) # 输出:('苹果', ['西瓜', '橙子'])
# 3. 只有一个元素的元组写法
# 注意:只有一个元素的元组要加逗号
single = (42,)
print(type(single)) # 输出:<class 'tuple'>
not_tuple = (42)
print(type(not_tuple)) # 输出:<class 'int'>
# 4. 元组可以包含可变对象
# 元组中可以包含列表,列表的内容可以变
combo = ("A", [1, 2])
combo[1][0] = 99 # 修改元组中列表的内容
print(combo) # 输出:('A', [99, 2])
# 5. 取出嵌套列表中的指定元素
# 这是一个三层嵌套的列表
data = [
["Tom", "Jerry", "Spike"],
["Python", "Java", "C++"],
["Alice", "Bob", "Eve"]
]
# 取出"Tom"
print(data[0][0]) # 输出:Tom
# 取出"Java"
print(data[1][1]) # 输出:Java
# 取出"Eve"
print(data[2][2]) # 输出:Eve
# 6. 判断变量类型
# 判断变量是不是元组
a = ()
b = (1)
c = [2]
d = (3,)
e = (4, 5, 6)
print(isinstance(a, tuple)) # True,空元组
print(isinstance(b, tuple)) # False,b是整数
print(isinstance(c, tuple)) # False,c是列表
print(isinstance(d, tuple)) # True,只有一个元素的元组
print(isinstance(e, tuple)) # True,多个元素的元组
1.2.4 范围(range)
表示整数序列,如
range(10)生成 0-9 的整数
1.3 映射类型
1.3.1 字典(dict)
用花括号
{}表示,由键值对组成,如{'name': 'Alice', 'age': 20}
# 1. 字典的创建与基本用法
# 创建一个字典,存储学生的分数
scores = {
"小明": 92,
"小红": 88,
"小刚": 75
}
print(scores) # 输出整个字典:{'小明': 92, '小红': 88, '小刚': 75}
# 通过名字查找分数
print(scores["小明"]) # 输出:92
# 2. 添加和修改字典中的数据
# 创建一个字典,存储学生的分数
scores = {
"小明": 92,
"小红": 88,
"小刚": 75
}
# 添加一个新同学的分数
scores["小丽"] = 81
print(scores) # 输出:{'小明': 92, '小红': 88, '小刚': 75, '小丽': 81}
# 修改已有同学的分数
scores["小红"] = 90
print(scores) # 输出:{'小明': 92, '小红': 90, '小刚': 75, '小丽': 81}
# 3. 判断key是否存在
# 创建一个字典,存储学生的分数
scores = {
"小明": 92,
"小红": 88,
"小刚": 75
}
# 检查"小刚"是否在字典中
print("小刚" in scores) # 输出:True
# 检查"小强"是否在字典中
print("小强" in scores) # 输出:False
# 4. 安全地获取字典中的值
# 创建一个字典,存储学生的分数
scores = {
"小明": 92,
"小红": 88,
"小刚": 75
}
# 直接用[]查找不存在的key会报错
# print(scores["小强"]) # 这一行会报 KeyError: '小强'
# 推荐用get方法,查不到时返回None或自定义的默认值
print(scores.get("小强")) # 输出:None
print(scores.get("小强", 0)) # 输出:0
# 5. 删除字典中的数据
# 创建一个字典,存储学生的分数
scores = {
"小明": 92,
"小红": 88,
"小刚": 75
}
# 删除"小刚"的分数
removed_score = scores.pop("小刚") # pop会返回被删除的值
print(removed_score) # 输出:75
print(scores) # 输出:{'小明': 92, '小红': 88}
# 6. 字典的key必须是不可变对象
# 字典的key可以是字符串、数字、元组等不可变类型
info = {
1001: "张三",
(1, 2): "坐标点"
}
print(info) # {1001: '张三', (1, 2): '坐标点'}
# 不能用列表作为key,否则会报错
wrong = {[1, 2, 3]: "错误"} # 这一行会报TypeError: unhashable type: 'list'
# 综合案例:学生信息表
# 创建一个学生信息表,key是学号,value是学生姓名
students = {
"202301": "王伟",
"202302": "李娜",
"202303": "赵强"
}
# 查询学号为"202302"的学生姓名
print(students.get("202302", "查无此人")) # 输出:李娜
# 删除学号为"202301"的学生
students.pop("202301")
print(students) # 输出:{'202302': '李娜', '202303': '赵强'}
1.3.1.1 字典和列表的区别
- 字典通过key查找value,速度非常快,适合做查找表。
- 列表只能通过下标查找,数据越多查找越慢。
- 字典占用内存较多,列表更节省空间。
- 字典的key必须是不可变类型,列表的元素类型没有限制。
1.3.1.2 总结
- 字典(dict)是一种通过key快速查找value的数据结构。
- 可以随时添加、修改、删除数据。
- key必须是不可变类型,value可以是任意类型。
- 字典在Python中非常常用,适合做各种查找表和映射关系。
1.4 集合类型
1.4.1 集合(set)
用花括号
{}表示,元素唯一且无序,如{1, 2, 3};集合(set)是一种无序、无重复元素的数据结构。你可以把它想象成一个“去重的盒子”,盒子里每个元素都独一无二,顺序不重要。
# 1. 集合的创建方法
# 直接用大括号创建集合
numbers = {1, 2, 3}
print(numbers) # 输出:{1, 2, 3}
# 用set()函数把列表转换为集合
fruits = set(["苹果", "香蕉", "苹果", "橙子"])
print(fruits) # 输出:{'香蕉', '苹果', '橙子'},自动去重
# 2. 集合的去重特性
# 集合会自动去掉重复的元素
colors = {"红", "绿", "蓝", "红", "蓝"}
print(colors) # 输出:{'红', '绿', '蓝'}
# 3. 添加和删除元素
# 创建一个集合
pets = {"猫", "狗"}
# 添加新元素
pets.add("兔子")
print(pets) # 输出:{'猫', '狗', '兔子'}
# 再次添加已存在的元素不会报错,也不会重复
pets.add("狗")
print(pets) # 输出:{'猫', '狗', '兔子'}
# 删除元素
pets.remove("猫")
print(pets) # 输出:{'狗', '兔子'}
# 4. 集合的数学操作
# 创建两个集合
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
# 交集:取两个集合都包含的元素
print(a & b) # 输出:{3, 4}
# 并集:取两个集合所有不重复的元素
print(a | b) # 输出:{1, 2, 3, 4, 5, 6}
# 5. 集合的元素类型要求
# 集合的元素必须是不可变类型,比如数字、字符串、元组
valid_set = {1, "hello", (2, 3)}
print(valid_set) # 输出:{1, 'hello', (2, 3)}
# 不能把列表放进集合,否则会报错
wrong_set = {[1, 2, 3]} # 这一行会报TypeError: unhashable type: 'list'
# 6. 不可变对象的理解
# 字符串是不可变对象,调用replace不会改变原字符串
text = "hello"
new_text = text.replace("h", "H")
print(text) # 输出:hello(原字符串没变)
print(new_text) # 输出:Hello(新字符串)
# 列表是可变对象,调用sort会改变原列表
nums = [3, 1, 2]
nums.sort()
print(nums) # 输出:[1, 2, 3]
# 综合案例:去除重复元素
# 有一个带重复元素的列表
raw_data = ["A", "B", "A", "C", "B", "D"]
# 用set去重
unique_data = set(raw_data)
print(unique_data) # 输出:{'A', 'B', 'C', 'D'}
1.4.1.1 总结
- 集合(set)是一种无序、无重复元素的数据结构。
- 可以用add添加元素,用remove删除元素。
- 支持交集、并集等数学操作。
- 集合的元素必须是不可变类型。
- 集合常用于去重、数学集合运算等场景。
1.4.2 冻结集合(frozenset)
不可修改的集合,如
frozenset({1, 2, 3})
1.5 其他类型
1.5.1 空值(None):
# 空值的使用
student_name = None # 表示学生姓名暂时未知
print(f"学生姓名:{student_name}") # 输出:学生姓名:None
1.5.2 变量(数据的容器)-变量就像是一个标签,可以贴在任何数据上:
# 变量的基本使用
score = 95 # 给变量score贴上95这个数字
name = "小红" # 给变量name贴上"小红"这个文字
is_passed = True # 给变量is_passed贴上True这个布尔值
# 变量的重新赋值
score = 98 # 把score的标签从95换成了98
print(f"{name}的分数是:{score}") # 输出:小红的分数是:98
# 弱类型
# Python是弱类型语言,变量不需要声明类型
# 变量可以随时赋值为不同类型的数据
# 变量的类型
# 使用type()函数查看变量的类型
print(type(score)) # 输出:<class 'int'>
print(type(name)) # 输出:<class 'str'>
print(type(is_passed)) # 输出:<class 'bool'>
# 多个变量同时赋值
x, y, z = 1, 2, 3
print(f"x={x}, y={y}, z={z}") # 输出:x=1, y=2, z=3
# 变量的交换
a = 1
b = 2
a, b = b, a # 交换a和b的值
print(f"a={a}, b={b}") # 输出:a=2, b=1
案例:创建一个简单的学生信息卡
# 创建一个学生信息卡
student_name = "小明"
student_age = 15
student_height = 1.75
student_score = 95.5
is_excellent = student_score >= 90
# 使用f-字符串格式化输出
print(f"""
学生信息卡
----------
姓名:{student_name}
年龄:{student_age}岁
身高:{student_height}米
分数:{student_score}分
是否优秀:{'是' if is_excellent else '否'}
""")
1.6 查看变量的数据类型
使用 type() 函数查看变量的数据类型
x = 10
print(type(x)) # 输出 <class 'int'>
y = [1, 2, 3]
print(type(y)) # 输出 <class 'list'>
2.字符串编码
2.1 什么是字符串?
在Python中,字符串就是一串字符,比如你的名字、地址、喜欢的电影名等。字符串可以用单引号'、双引号",甚至三引号'''或"""括起来。
# 用单引号定义字符串
nickname = '小明'
# 用双引号定义字符串
city = "北京"
# 用三引号定义多行字符串
poem = """春眠不觉晓,
处处闻啼鸟。"""
print(nickname) # 输出:小明
print(city) # 输出:北京
print(poem) # 输出多行诗句
2.2 字符串的拼接与重复
你可以把多个字符串合成一个,也可以让字符串重复多次。
# 字符串拼接
first_name = "张"
last_name = "三"
full_name = first_name + last_name # 用+号拼接
print(full_name) # 输出:张三
## 字符串和数字的拼接
# 字符串和数字拼接时,不能直接拼接,需要先将数字转换为字符串
age = 20
message = "我今年" + str(age) + "岁"
print(message) # 输出:我今年20岁
# 字符串重复
laugh = "哈" * 5 # 字符串可以和数字相乘,表示重复
print(laugh) # 输出:哈哈哈哈哈
2.3 字符串的索引和切片
字符串其实是一个字符的序列,每个字符都有编号(从0开始),可以像操作列表一样操作字符串。
# 索引
word = "Python"
print(word[0]) # 输出第一个字符:P
print(word[-1]) # 输出最后一个字符:n
# 切片
greeting = "Hello, world!"
print(greeting[0:5]) # 输出:Hello(从第0到第4个字符,不包括第5个)
print(greeting[7:]) # 输出:world!(从第7个字符到结尾)
print(greeting[:5]) # 输出:Hello(从开头到第4个字符)
2.4 字符串常用方法
Python为字符串提供了很多实用的方法,比如大小写转换、查找、替换等。
# 大小写转换
text = "Python is Fun!"
print(text.lower()) # 全部转为小写:python is fun!
print(text.upper()) # 全部转为大写:PYTHON IS FUN!
# 查找和替换
sentence = "I love apples, apples are sweet."
print(sentence.find("apples")) # 查找'apples'第一次出现的位置,输出:7
print(sentence.replace("apples", "oranges")) # 替换所有'apples'为'oranges'
2.5 字符串格式化
有时候我们需要把变量的值插入到字符串中,Python有多种方式实现。
2.5.1 百分号(%)格式化
# 百分号格式化
name = "小红"
age = 20
# 这是Python中的百分号格式化字符串方法
# %s 是一个占位符,表示将被字符串替换
# %d 是一个占位符,表示将被整数替换
# 括号中的(name, age)是要插入到字符串中的变量
# 变量会按顺序替换占位符:name替换%s,age替换%d
print("大家好,我叫%s,今年%d岁。" % (name, age)) # %s表示字符串,%d表示整数
# 常见的格式化占位符:
# %s - 字符串
# %d - 整数
# %f - 浮点数
# %.2f - 保留两位小数的浮点数
# %% - 输出百分号本身
2.5.2 format方法
# format方法
fruit = "香蕉"
price = 3.5
print("今天的{}价格是{}元一斤。".format(fruit, price)) # 用{}占位,后面用format填充
2.5.3 f-string(推荐,Python 3.6及以上)
# f-string格式化
score = 98
student = "李雷"
print(f"{student}的考试成绩是{score}分。") # 变量名直接写在{}里
2.6 转义字符
有些字符在字符串里有特殊含义,比如换行、制表符、引号等,需要用“\”来转义。
# 换行和制表符
info = "姓名:小明\n性别:男\t年龄:18"
print(info)
# 输出:
# 姓名:小明
# 性别:男 年龄:18
# 字符串中包含引号
quote = "他说:\"Python真有趣!\""
print(quote) # 输出:他说:"Python真有趣!"
2.7 字符串与编码
2.7.1 字符编码的概念
计算机只能处理数字,字符串在存储和传输时需要转换为数字(字节)。常见的编码有ASCII、UTF-8、GBK等。
2.7.2 编码与解码
- 编码(encode) :把字符串转成字节
- 解码(decode) :把字节转回字符串
# 编码为UTF-8字节
msg = "你好,世界"
msg_bytes = msg.encode("utf-8") # 编码为字节
print(msg_bytes) # 输出:b'\xe4\xbd\xa0\xe5\xa5\xbd\xef\xbc\x8c\xe4\xb8\x96\xe7\x95\x8c'
# 解码回字符串
msg_str = msg_bytes.decode("utf-8") # 解码为字符串
print(msg_str) # 输出:你好,世界
2.7.3 编码错误的常见情况
在Python中,当程序执行过程中遇到错误时,会抛出异常。我们可以使用try-except语法来捕获并处理这些异常,避免程序崩溃。
# 错误示例:用GBK解码UTF-8字节
try:
msg = "你好,世界"
msg_bytes = msg.encode("utf-8") # 编码为字节
wrong_str = msg_bytes.decode("gbk") # 这里会报错,因为尝试用GBK解码UTF-8编码的字节
except UnicodeDecodeError as e:
# except 代码块:捕获并处理特定类型的异常
# UnicodeDecodeError 是解码错误的异常类型
# as e 将异常对象赋值给变量e,以便后续使用
print("解码出错:", e) # 打印错误信息
2.8 字符串遍历与判断
你可以像遍历列表一样遍历字符串的每个字符,还可以判断字符串内容。
# 遍历字符串
for char in "Python":
print(char) # 依次输出每个字符
# 判断字符串内容
email = "user@example.com"
print(email.startswith("user")) # 判断是否以"user"开头,输出:True
print(email.endswith(".com")) # 判断是否以".com"结尾,输出:True
print(email.isdigit()) # 判断是否全是数字,输出:False
2.9 lower
str.lower() 是一个字符串方法,用于将字符串中的所有大写字母转换为小写字母
它可以通过两种方式调用:
- 作为实例方法:字符串实例.lower()
- 作为类方法:str.lower(字符串实例)
# 示例1:作为实例方法
s1 = "HELLO WORLD"
print(s1.lower()) # 输出: "hello world"
# 示例2:作为类方法
s2 = "PYTHON编程"
print(str.lower(s2)) # 输出: "python编程"
# 注意:str.lower()只会转换ASCII字符中的大写字母,不会影响非字母字符或非ASCII字符
s3 = "ABC123!@#中文"
print(s3.lower()) # 输出: "abc123!@#中文"
# 在列表生成式中使用str.lower()和实例方法.lower()效果相同
# 但使用实例方法更为常见和直观
2.10 常见问题
- 字符串不可变,修改字符串会生成新对象
- 中文字符串建议统一使用UTF-8编码
- 处理文件时要注意文件的编码格式
# 字符串不可变的例子
s = "hello"
s2 = s.replace("h", "H")
print(s) # 输出:hello(原字符串没变)
print(s2) # 输出:Hello(新字符串)
3.if条件判断
# 1. 基本用法
# 假设我们要判断一个人的年龄是否成年
age = 21 # 定义一个变量age,表示年龄
if age >= 18: # 如果年龄大于等于18
print("你已经成年啦!") # 满足条件时执行
print("可以独立做很多事情。") # 这行也会被执行
# 如果age小于18,这两行不会被执行
# 2. if...else:有选择地执行
# 判断一个人是否可以考驾照
age = 15
if age >= 18:
print("你可以考驾照了!") # 如果年龄大于等于18,执行这里
else:
print("你还未成年,不能考驾照。") # 否则执行这里
# 3. if...elif...else:多种情况分支
# 判断考试成绩等级
score = 72
if score >= 90:
print("优秀")
elif score >= 75:
print("良好")
elif score >= 60:
print("及格")
else:
print("不及格")
# 程序会从上往下判断,遇到第一个满足条件的分支就执行,然后跳过后面的分支
# 4. 条件判断的顺序很重要
# 看看下面的例子
temperature = 30
if temperature > 0:
print("天气温暖")
elif temperature > 20:
print("天气炎热")
else:
print("天气寒冷")
# 结果会输出"天气温暖",因为第一个条件已经满足,后面的elif不会再判断
# 5. 条件可以是任意表达式
# 判断一个字符串是否为空
name = ""
if name: # 空字符串会被当作False
print("名字不为空")
else:
print("名字是空的")
# 判断一个列表是否有内容
numbers = [1, 2, 3]
if numbers: # 非空列表会被当作True
print("列表有内容")
else:
print("列表是空的")
numbers2 = []
if numbers2: # 空列表会返回False
print("列表有内容")
else:
print("列表是空的")
# 6. input输入与类型转换
# input()得到的内容类型是字符串
user_input = input("请输入你的年龄:")
print(type(user_input)) # 输出:<class 'str'>
user_input = input("请输入你的年龄:")
# 要和数字比较时需要用int()转换类型
age = int(user_input)
if age >= 18:
print("你已经成年啦!")
else:
print("你还未成年,不能考驾照。")
# 如果直接拿字符串和数字比较,会报错
# TypeError: '>=' not supported between instances of 'str' and 'int'
age = input("请输入你的年龄:")
if age >= 18:
print("你已经成年啦!")
else:
print("你还未成年,不能考驾照。")
# 7. 异常情况:输入不是数字怎么办?
# 如果用户输入的不是数字,int()会报错
user_input = input("请输入一个数字:")
try:
number = int(user_input) # 尝试转换为整数
print("你输入的数字是:", number)
except ValueError:
print("输入的内容不是有效的数字,请重新输入。")
# 综合案例:BMI健康指数判断
# 小明的身高和体重
height = 1.75 # 单位:米
weight = 80.5 # 单位:千克
# 计算BMI指数,公式:体重 / (身高的平方)
bmi = weight / (height ** 2)
print(f"小明的BMI指数为:{bmi:.2f}") # 保留两位小数
# 根据BMI指数判断健康状况
if bmi < 18.5:
print("体重过轻")
elif bmi < 25:
print("体重正常")
elif bmi < 28:
print("体重偏重")
elif bmi < 32:
print("肥胖")
else:
print("严重肥胖")
4. match 语句
在实际编程中,我们经常需要根据变量的不同取值执行不同的操作。传统的做法是用一连串的 if...elif...else 语句,但这样代码会变得很长、很难读。Python 3.10 及以上版本引入了 match 语句,让多分支判断变得更清晰、更优雅。
# 1. match 语句的基本用法
# 假设我们要根据天气情况给出不同的建议
weather = "rainy"
# 使用match语句进行多分支判断
match weather:
case "sunny":
print("天气晴朗,适合出门散步。") # 如果是晴天
case "rainy":
print("下雨了,记得带伞。") # 如果是雨天
case "snowy":
print("下雪了,注意保暖。") # 如果是雪天
case _:
print("无法识别的天气类型。") # 其他情况
# 2. 匹配多个值和范围
# 判断一个月份属于哪个季节
month = 4
match month:
case 12 | 1 | 2:# 12月、1月、2月属于冬季
print("冬季")
case 3 | 4 | 5:# 3月、4月、5月属于春季
print("春季")
case 6 | 7 | 8:# 6月、7月、8月属于夏季
print("夏季")
case 9 | 10 | 11:# 9月、10月、11月属于秋季
print("秋季")
case _:# 其他情况
print("月份无效")
# 3. 带条件的匹配(守卫)
# 判断分数等级
score = 85
match score:
case s if s >= 90:
print("成绩优秀")
case s if 80 <= s < 90:
print("成绩良好")
case s if 60 <= s < 80:
print("成绩及格")
case _:
print("成绩不及格")
# 4. 匹配列表和解包
# 假设有一个命令行参数列表
command = ["run", "main.py", "--debug"]
match command:
case ["run"]:
print("缺少要运行的文件名。")
case ["run", filename]:
print(f"正在运行文件:{filename}")
case ["run", filename, *options]:
print(f"运行{filename},附加参数:{options}")
case ["help"]:
print("显示帮助信息。")
case _:
print("未知命令。")
# `*options`表示匹配剩下的所有参数,放到一个列表里。
# `case _:`用来处理所有未被前面分支匹配到的情况。
5. 循环
5.1 for 循环基本用法
# 假设有一个学生名单
students = ["小明", "小红", "小刚"]
# 用for循环依次打印每个学生的名字
for student in students:
print(student) # 每次循环,student变量会依次等于列表中的每个名字
# 小明
# 小红
# 小刚
5.2 for 循环与 range 的结合
# 计算1到10的累加和
total = 0 # 用于累加的变量
# 使用for循环遍历1到10的整数序列
# 使用range()函数生成1到10的整数序列
# range()函数可以生成一个整数序列,包含从开始到结束(不包含结束)的整数
# 例如,range(1, 11)会生成1到10的整数序列
# range(5) 会生成0到4的整数序列 [0, 1, 2, 3, 4]
for number in range(1, 11):
total += number # 每次循环把当前数字加到total上
print("1到10的和是:", total) # 输出:1到10的和是:55
# 使用for循环遍历0到4的整数序列
# 使用range()函数生成0到4的整数序列
# range()函数可以生成一个整数序列,包含从开始到结束(不包含结束)的整数
# 例如,range(5)会生成0到4的整数序列
for i in range(5): # range(5)生成0,1,2,3,4
print(i)
# for循环可用于循环字符串
for char in "Hello":
print(char)
5.3 while 循环:只要条件成立就一直循环
# 用while循环打印1到5
n = 1
while n <= 5: # 只要n小于等于5就继续循环
print(n)
n += 1 # 每次循环n加1
5.4 break:遇到特殊情况提前结束循环
# 打印1到100,但遇到第一个能被7整除的数就停止
for i in range(1, 101):
if i % 7 == 0: # 如果i能被7整除
print("遇到第一个能被7整除的数:", i)
break # 立即结束整个循环
print(i)
5.5 continue:跳过本次循环,直接进入下一轮
# 打印1到10中的所有奇数
for i in range(1, 11):
if i % 2 == 0: # 如果是偶数
continue # 跳过本次循环,后面的print不会执行
print(i) # 只会打印奇数
5.6 综合案例
# 给每个同学打印Hello, xxx!
names = ["Tom", "Jerry", "Spike"]
for name in names:
print(f"Hello, {name}!") # f-string格式化输出
5.7 死循环示例
# 下面的代码会无限循环,除非强制停止
while True:
print("这是一个死循环,按Ctrl+C可以终止程序。")
5.8 总结
- for循环适合遍历列表、字符串、range等序列。
- while循环适合只要条件成立就一直执行的场景。
- break可以提前终止循环,continue可以跳过本轮循环。
- 死循环会让程序永远运行下去,通常要避免。
6. 切片
切片是Python中一种强大的数据操作方式,它允许我们从序列(如列表、元组、字符串)中提取部分元素。
6.1 基础切片操作
# 创建一个包含5个名字的列表
names = ['小明', '小红', '小华', '小李', '小张']
# 获取前三个名字
first_three = names[0:3] # 从索引0开始,到索引3结束(不包含3)
print(first_three) # 输出: ['小明', '小红', '小华']
# 当从开头开始切片时,可以省略起始索引
first_three_short = names[:3] # 效果同上
print(first_three_short) # 输出: ['小明', '小红', '小华']
6.2 切片的基本语法
切片的基本语法是:序列[起始索引:结束索引:步长]
# 创建一个数字列表
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 获取中间部分
middle = numbers[2:5] # 获取索引2到4的元素
print(middle) # 输出: [2, 3, 4]
# 使用步长
# 步长为2,每隔一个取一个元素,注意是包括第一个元素,从0开始
every_other = numbers[::2] # 每隔一个取一个元素
print(every_other) # 输出: [0, 2, 4, 6, 8]
6.3 负索引切片
Python支持使用负索引进行切片,-1表示最后一个元素:
# 使用负索引
fruits = ['苹果', '香蕉', '橙子', '葡萄', '西瓜']
# 获取最后两个水果
last_two = fruits[-2:] # 从倒数第二个到末尾
print(last_two) # 输出: ['葡萄', '西瓜']
# 获取倒数第二个到倒数第三个
middle_fruits = fruits[-3:-1] # 从倒数第三个到倒数第二个
print(middle_fruits) # 输出: ['橙子', '葡萄']
6.4 字符串切片
# 字符串切片示例
text = "Python编程很有趣"
# 获取前6个字符
first_five = text[:6] # 输出: "Python"
print(first_five)
# 获取最后3个字符
last_three = text[-3:] # 输出: "很有趣"
print(last_three)
# 每隔一个字符取一个
every_other_char = text[::2] # 输出: "Pto编很趣"
print(every_other_char)
6.5 应用示例
# 创建一个学生成绩列表
scores = [85, 92, 78, 90, 88, 95, 82, 87, 91, 89]
# 获取前5名学生的成绩
# 使用sorted函数对scores列表进行排序,并使用reverse=True参数进行降序排序
# 然后使用切片[:5]获取前5名学生的成绩
top_five = sorted(scores, reverse=True)[:5]
print("前5名成绩:", top_five) # 输出: [95, 92, 91, 90, 89]
# 获取后3名学生的成绩
# 使用sorted函数对scores列表进行排序,并使用reverse=False参数进行升序排序
# 然后使用切片[:3]获取后3名学生的成绩
bottom_three = sorted(scores)[:3]
print("后3名成绩:", bottom_three) # 输出: [78, 82, 85]
6.6 总结
- 切片操作可以轻松获取序列中的部分元素
- 切片语法:
序列[起始:结束:步长] - 可以使用正索引和负索引
- 适用于列表、元组、字符串等序列类型
- 通过合理使用切片,可以大大简化代码
7. 迭代
迭代是Python中一种优雅的遍历数据的方式,它让我们能够轻松地访问序列中的每个元素。
7.1 基础迭代操作
# 创建一个水果列表
fruits = ['苹果', '香蕉', '橙子', '葡萄']
# 使用for循环遍历列表
for fruit in fruits: # 每次循环,fruit变量会依次获取列表中的一个元素
print(f"我喜欢吃{fruit}") # 打印每个水果
7.2 字典的迭代
# 创建一个学生成绩字典
scores = {
'小明': 95,
'小红': 88,
'小华': 92
}
# 迭代字典的键
print("学生名单:")
for name in scores: # 默认迭代字典的键
print(name)
# 迭代字典的值
print("\n成绩列表:")
for score in scores.values(): # 使用values()方法获取所有值
print(score)
# 同时迭代键和值
print("\n学生成绩:")
for name, score in scores.items(): # 使用items()方法同时获取键和值
print(f"{name}的成绩是{score}分")
7.3 整数不是可迭代对象
# 创建一个整数
number = 10
# 迭代整数
print("整数中的每个数字:")
for digit in number: # TypeError: 'int' object is not iterable
print(digit)
7.4 字符串的迭代
# 创建一个字符串
message = "你好,Python!"
# 迭代字符串中的每个字符
print("字符串中的每个字符:")
for char in message: # 每次循环,char变量会获取一个字符
print(char)
7.5 使用enumerate进行索引迭代
# 同时获取元素的索引和值:
# 创建一个购物清单
shopping_list = ['牛奶', '面包', '鸡蛋', '水果']
# 使用enumerate同时获取索引和值
print("购物清单:")
for index, item in enumerate(shopping_list): # enumerate会返回(索引, 值)对
print(f"{index + 1}. {item}") # 索引从0开始,所以加1显示
7.6 应用示例
# 创建一个学生信息列表,列表的每个元素是一个元组,元组中包含学生的姓名、年龄和性别
students = [
('小明', 15, '男'),
('小红', 14, '女'),
('小华', 15, '男'),
('小丽', 14, '女')
]
# 使用迭代处理学生信息
print("学生信息统计:")
boys = 0 # 男生计数
girls = 0 # 女生计数
total_age = 0 # 年龄总和
for name, age, gender in students: # 解包元组中的值
total_age += age # 累加年龄
if gender == '男':
boys += 1
else:
girls += 1
# 计算平均年龄
average_age = total_age / len(students)
print(f"班级共有{len(students)}名学生")
print(f"男生:{boys}人,女生:{girls}人")
print(f"平均年龄:{average_age:.1f}岁")
7.7 总结
- 迭代是Python中遍历数据的基本方式
- 可以使用for循环遍历任何可迭代对象
- 字典可以通过keys()、values()、items()方法进行不同方式的迭代
- enumerate()函数可以同时获取索引和值
- 迭代操作让代码更简洁、更易读
8. 列表生成式
列表生成式是Python中一种优雅的创建列表的方式,它让我们能够用一行代码完成复杂的列表创建操作。
8.1 基础列表生成式
# 创建一个包含1到10的平方的列表
# 列表生成式的基本语法:[表达式 for 变量 in 可迭代对象]
# 这里的表达式是 x * x,变量是 x,可迭代对象是 range(1, 11)
# 它会遍历 range(1, 11) 中的每个数字,计算其平方,然后放入新列表中
squares = [x * x for x in range(1, 11)] # 遍历1到10,计算每个数的平方
print(squares) # 输出: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 对比传统方法
squares_traditional = [] # 创建空列表
for x in range(1, 11): # 使用for循环
squares_traditional.append(x * x) # 添加平方数
print(squares_traditional) # 输出相同结果
8.2 带条件的列表生成式
# 在列表生成式中添加条件来筛选元素:
# 创建一个只包含偶数的平方的列表
# 列表生成式的基本语法:[表达式 for 变量 in 可迭代对象 if 条件]
# 这里的表达式是 x * x,变量是 x,可迭代对象是 range(1, 11),条件是 x % 2 == 0
# 它会遍历 range(1, 11) 中的每个数字,如果它是偶数,则计算其平方,然后放入新列表中
even_squares = [x * x for x in range(1, 11) if x % 2 == 0] # 只选择偶数
print(even_squares) # 输出: [4, 16, 36, 64, 100]
# 创建一个包含正数的列表
numbers = [-2, -1, 0, 1, 2, 3]
# 列表生成式的基本语法:[表达式 for 变量 in 可迭代对象 if 条件]
# 这里的表达式是 x,变量是 x,可迭代对象是 numbers,条件是 x > 0
# 它会遍历 numbers 中的每个数字,如果它是正数,则放入新列表中
positive_numbers = [x for x in numbers if x > 0] # 只选择正数
print(positive_numbers) # 输出: [1, 2, 3]
8.3 多重循环的列表生成式
# 列表生成式支持多重循环,可以生成复杂的组合:
# 创建一个包含所有可能的字母组合的列表
letters = ['A', 'B', 'C']
numbers = ['1', '2', '3']
# 列表生成式的基本语法:[表达式 for 变量 in 可迭代对象 for 变量 in 可迭代对象]
# 这里的表达式是 letter + number,变量是 letter 和 number,可迭代对象是 letters 和 numbers
# 它会遍历 letters 中的每个字母,然后遍历 numbers 中的每个数字,将它们组合起来,然后放入新列表中
combinations = [letter + number for letter in letters for number in numbers] # 双重循环
print(combinations) # 输出: ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
8.4 应用示例
# 创建一个学生成绩列表
scores = [
{'name': '小明', 'score': 85},
{'name': '小红', 'score': 92},
{'name': '小华', 'score': 78},
{'name': '小李', 'score': 90}
]
# 获取所有及格学生的名字
passing_students = [student['name'] for student in scores if student['score'] >= 60]
print("及格学生:", passing_students) # 输出: ['小明', '小红', '小华', '小李']
# 计算每个学生的成绩等级
grade_list = [
f"{student['name']}: {'优秀' if student['score'] >= 90 else '良好' if student['score'] >= 80 else '及格' if student['score'] >= 60 else '不及格'}"
for student in scores
]
print("成绩等级:", grade_list)
8.5 列表生成式与传统for循环的效率比较
列表生成式通常被认为是一种更简洁、更优雅的创建列表的方式
8.5.1 列表生成式的效率
- 执行速度:列表生成式在Python内部是经过优化的,通常比等效的for循环执行得更快。
- 内存使用:列表生成式在内部一次性分配内存,而不是像for循环那样逐步扩展列表。
- 代码简洁:用一行代码替代多行for循环,减少了出错的可能性。
8.5.2 传统for循环的效率
- 执行速度:传统for循环在Python中执行速度相对较慢,尤其是在处理大型数据集时。
- 内存使用:传统for循环需要多次扩展列表,导致内存使用效率较低。
- 代码复杂:传统for循环的代码行数较多,容易出错。
8.5.3 结论
- 列表生成式在执行速度和内存使用上通常比传统for循环更高效。
- 列表生成式在代码简洁性上具有明显优势。
- 在处理大型数据集时,列表生成式通常比传统for循环更高效。
8.6 总结
- 列表生成式可以大大简化列表的创建过程
- 可以使用条件语句筛选元素
- 支持多重循环生成复杂组合
- 代码更简洁、更易读
- 适合处理数据转换和筛选
9. 正则表达式
9.1 正则表达式的基本语法
正则表达式本质上就是一串特殊的字符,每个字符或符号都有特定含义。
下面是一些常用的正则表达式符号及其作用:
\d:匹配一个数字(0-9)\w:匹配一个字母、数字或下划线.:匹配任意单个字符(除了换行符)*:匹配前面的内容出现0次或多次+:匹配前面的内容出现1次或多次?:匹配前面的内容出现0次或1次{n}:匹配前面的内容出现n次{n,m}:匹配前面的内容出现n到m次[]:匹配括号内的任意一个字符^:匹配字符串的开头$:匹配字符串的结尾|:表示“或”,比如A|B可以匹配A或B
9.2 基础匹配
re.match(pattern, string) :从字符串开头匹配正则表达式。
import re # 导入正则表达式模块
# 匹配3位数字
print(re.match(r'\d\d\d', '123')) # 匹配成功,输出Match对象
# 输出:<re.Match object; span=(0, 3), match='123'>
# 匹配字母+字母+数字
print(re.match(r'\w\w\d', 'ab3')) # 匹配成功
# 匹配以py开头,后面跟任意一个字符
print(re.match(r'py.', 'pyx')) # 匹配成功
# 注:r前缀表示“原始字符串”,这样写正则表达式时不用担心转义问题。
**1. `re.Match object`**
- 这是 Python `re` 模块返回的匹配对象,表示正则表达式匹配成功。
- 如果匹配失败,`re.match()` 会返回 `None`。
**2. `span=(0, 3)`**
- 表示匹配到的子串在目标字符串中的 **起始和结束位置(左闭右开区间)** 。
- `0` 是匹配的起始索引(包含)
- `3` 是匹配的结束索引(不包含)
- 说明匹配的字符串是目标字符串的第 `0` 到 `2` 个字符(Python 字符串索引从 `0` 开始)。
**3. `match='123'`**
- 表示实际匹配到的字符串内容。
- 在这个例子中,正则表达式 `\d\d\d` 匹配了 `'123'`。
9.3 判断字符串是否符合某种格式
# 判断一个字符串是不是合法的电话号码(区号-号码):
import re
# 匹配3位数字-3到8位数字
pattern = r'^\d{3}-\d{3,8}$'
print(re.match(pattern, '010-12345')) # 匹配成功
print(re.match(pattern, '010 12345')) # 匹配失败(有空格)
# 注: `^`表示开头,`$`表示结尾,保证整个字符串都要符合规则。
9.4 切分字符串
# 有时候我们需要把字符串按空格、逗号等分割成列表。用正则表达式可以一次性处理多种分隔符:
import re
text = 'a,b;; c d'
# 匹配空格、逗号、分号中任意一个或多个
result = re.split(r'[\s,;]+', text)
print(result) # 输出:['a', 'b', 'c', 'd']
# 注: `[\s,;]+`表示空格、逗号、分号中任意一个,出现一次或多次。
9.5 提取子串(分组)
正则表达式可以用括号()把需要提取的部分分组,方便后续获取:
m.groups() :返回所有捕获组(括号 () 内的匹配内容)。
m.group(n) :返回第n个捕获组(括号 () 内的匹配内容)。
import re
# 匹配区号和本地号码,并分组提取
m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
if m:
print(m.group(1)) # 输出:010(区号)
print(m.group(2)) # 输出:12345(本地号码)
注: `group(0)`是整个匹配内容,`group(1)`、`group(2)`分别是第1、2个括号里的内容。
9.6 匹配变量名、邮箱等复杂规则
[a-zA-Z_][0-9a-zA-Z_]*:匹配Python合法变量名(字母或下划线开头,后面跟字母、数字或下划线)
\w+@\w+.\w+:简单匹配邮箱(实际邮箱规则更复杂)
9.7 贪婪与非贪婪匹配
正则默认是“贪婪”的,会尽可能多地匹配字符。
如果想让它“少匹配”,可以在量词后加?,变成“非贪婪”:
import re
# 贪婪匹配
m1 = re.match(r'^(\d+)(0*)$', '102300')
print(m1.groups()) # 输出:('102300', '')
# 非贪婪匹配
m2 = re.match(r'^(\d+?)(0*)$', '102300')
print(m2.groups()) # 输出:('1023', '00')
**(1) 贪婪匹配 `r'^(\d+)(0*)$'`**
`^`:匹配字符串开头。
`(\d+)`:**贪婪匹配** 1 个或多个数字(`+` 是贪婪的,会尽可能匹配更多字符)。
`(0*)`:匹配 0 个或多个 `0`(`*` 也是贪婪的,但前面的 `\d+` 已经匹配了所有数字)。
`$`:匹配字符串结尾。
**匹配过程**:
`\d+` 贪婪匹配,直接吃掉整个 `'102300'`。
`0*` 只能匹配剩下的空字符串 `''`(因为 `\d+` 已经匹配了所有数字)。
最终分组:
`(\d+)` → `'102300'`
`(0*)` → `''`
输出:('102300', '')
**(2) 非贪婪匹配 `r'^(\d+?)(0*)$'`**
`(\d+?)`:**非贪婪匹配** 1 个或多个数字(`+?` 是非贪婪的,尽可能匹配最少字符)。
`(0*)`:仍然贪婪匹配 `0`。
**匹配过程**:
`\d+?` 非贪婪匹配,只匹配 `'1'`(最小匹配),但为了满足后面的 `(0*)$`,它必须匹配到 `'1023'`(否则 `(0*)` 无法匹配剩余部分)。
`0*` 匹配剩下的 `'00'`。
最终分组:
`(\d+?)` → `'1023'`(尽可能少匹配,但仍要保证整个正则能匹配)
`(0*)` → `'00'`
输出:('1023', '00')
9.8 正则表达式在Python中的使用方法
Python的
re模块提供了多种常用方法:
re.match(pattern, string):从头开始匹配re.search(pattern, string):搜索整个字符串re.split(pattern, string):按正则分割字符串re.findall(pattern, string):找出所有匹配内容re.sub(pattern, repl, string):替换匹配内容
9.9 常用方法
import re
# search
m = re.search(r'\d+', 'a1b22c333')
print(m.group()) # 输出:1
# findall
numbers = re.findall(r'\d+', 'a1b22c333')
print(numbers) # 输出:['1', '22', '333']
# 替换所有数字为X
result = re.sub(r'\d+', 'X', 'a1b22c333')
print(result) # 输出:aXbXcX
9.10 正则表达式的预编译
如果你需要多次使用同一个正则表达式,可以先“编译”它,提高效率:
import re
# 预编译正则表达式
email_pattern = re.compile(r'^\w+@\w+\.\w+$')
# 多次使用
print(email_pattern.match('test@abc.com')) # 匹配成功
print(email_pattern.match('bad-email')) # 匹配失败
9.11 验证邮箱地址
# 判断邮箱地址是否合法:
import re
def is_valid_email(addr):
# 匹配邮箱的正则表达式:用户名@域名
pattern = r'^[\w\.]+@\w+\.\w+$'
# 如果匹配成功,返回True,否则返回False
return re.match(pattern, addr) is not None
# 测试
print(is_valid_email('someone@gmail.com')) # True
print(is_valid_email('bill.gates@microsoft.com')) # True
print(is_valid_email('bob#example.com')) # False
print(is_valid_email('mr-bob@example.com')) # False
# 注: 这里用户名允许字母、数字、下划线和点,域名部分只允许字母和点。
9.12 提取带名字的邮箱
# 有些邮箱地址前面带有名字,比如`<Tom Paris> tom@voyager.org`。我们希望提取出名字部分:
import re
def name_of_email(addr):
# 匹配带名字的邮箱
m = re.match(r'^<([\w\s]+)>\s*([\w\.]+)@(\w+\.\w+)$', addr)
if m:
return m.group(1) # 返回名字部分
# 匹配不带名字的邮箱
m = re.match(r'^([\w\.]+)@(\w+\.\w+)$', addr)
if m:
return m.group(1) # 返回邮箱用户名
return None
# 测试
print(name_of_email('<Tom Paris> tom@voyager.org')) # Tom Paris
print(name_of_email('tom@voyager.org')) # tom
# 先尝试匹配带名字的格式,如果不匹配再尝试普通邮箱格式。