Python 基础语法学习笔记(上篇:基础 ~ 函数 ~ 模块)
涵盖 Python 基础语法、数据类型、流程控制、数据容器、函数、模块六大板块。
目录
- 第一章:初识 Python(01-05)
- 1.1 Hello World 与 print 输出
- 1.2 字面量
- 1.3 变量
- 1.4 标识符与字符串格式化
- 1.5 键盘输入 input()
- 第二章:流程控制
- 2.1 条件语句 if / elif / else
- 2.2 模式匹配 match / case(Python 3.10+)
- 2.3 for 循环
- 2.4 while 循环
- 2.5 for 与 while 对比
- 2.6 循环控制语句 break / continue / pass
- 2.7 while...else / for...else
- 2.8 嵌套循环与 99 乘法表
- 2.9 综合案例:猜数字游戏
- 第三章:数据容器(08-18)
- 3.1 列表 list
- 3.2 字符串常用方法
- 3.3 元组 tuple
- 3.4 集合 set
- 3.5 字典 dict
- 3.6 综合案例
- 3.7 列表推导式(List Comprehension)
- 3.8 深拷贝与浅拷贝(面试高频)
- 第四章:函数(19-27)
- 4.1 函数基础
- 4.2 函数进阶
- 4.3 Lambda 匿名函数
- 4.4 递归
- 4.5 类型注解
- 4.6 装饰器(Decorator)
- 4.7 迭代器与生成器
- 4.8 常用内置函数速查
- 第五章:模块与包(28-32)
- 5.1 模块的概念与导入方式
- 5.2 name 与 all
- 5.3 包(Package)
第一章:初识 Python(01-05)
1.1 Hello World 与 print 输出
# 这是注释
print("Hello World")
print("Hello Python")
核心知识点:
| 知识点 | 说明 |
|---|---|
print() | Python 内置输出函数,将内容打印到控制台 |
# | 单行注释标记,# 后面的内容不会被执行 |
| 字符串 | 用引号包裹的文本,单引号 '...' 或双引号 "..." 均可 |
| 换行拼接 | 使用 \n 换行符 + + 运算符拼接多行字符串 |
变量定义与拼接输出示例:
line1 = "###########"
line2 = "# 白日依山尽 #"
# 用换行符拼接所有行并输出
print(line1 + "\n" + line2)
1.2 字面量
字面量是代码中直接写出的固定值,Python 支持以下字面量类型:
| 类型 | 关键字 | 示例 | 说明 |
|---|---|---|---|
| 整数 | int | 100 | 没有小数点的数字 |
| 浮点数 | float | 3.14 | 带小数点的数字 |
| 布尔值 | bool | True / False | 逻辑真/假 |
| 字符串 | str | "hello python" | 文本数据 |
| 空值 | NoneType | None | 表示"什么都没有" |
重要特性:布尔值可以参与运算
print(100 + True) # 输出 101(True 被当作 1)
print(100 + False) # 输出 100(False 被当作 0)
1.3 变量
变量是程序中用来存储数据的容器。
定义格式:
变量名 = 值
核心特性:
num = 114.1 # 定义变量
num = num + 11 # 可以重新计算
num = "hello world" # Python 是动态类型,变量可以改变数据类型
批量定义多个变量:
first, two = 12, 13 # 一行定义多个变量
print(first, two) # 输出:12 13
1.4 标识符与字符串格式化
标识符是为变量、函数、类等元素所起的名字。
字符串格式化两种方式:
方式一:% 占位符(传统方式)
name = "张三"
age = 18
print("大家好,我是%s, 今年%s岁" % (name, age))
常用占位符:
| 占位符 | 说明 |
|---|---|
%s | 字符串 |
%d | 整数 |
%f | 浮点数 |
方式二:f-string(推荐,Python 3.6+)
name = "张三"
age = 18
print(f"大家好,我是{name}, 今年{age}岁")
f-string 可以直接在 {} 中嵌入变量名或表达式,更直观、更推荐。
1.5 键盘输入 input()
name = input("请输入您的姓名:")
age = input("请输入您的年龄: ")
print(f"您的姓名是{name}, 年龄为{age}")
关键注意事项:
input()返回的永远是字符串str类型- 如果需要数字,必须手动转换:
int(input("请输入数字: ")) input()会阻塞程序,等待用户输入后才继续执行
第二章:流程控制
流程控制是指通过特定的语句来改变代码的执行顺序,使程序能够根据不同条件做出不同的判断,或者重复执行某些操作。Python 中有三大类流程控制语句:条件语句、循环语句、循环控制语句。
2.1 条件语句 if / elif / else
条件语句用于根据不同的条件执行不同的代码块。
2.1.1 语法定义
# 形式一:单条件
if 条件:
代码块
# 形式二:二选一
if 条件:
代码块A
else:
代码块B
# 形式三:多条件分支
if 条件1:
代码块A
elif 条件2:
代码块B
elif 条件3:
代码块C
else:
代码块D # 以上条件都不满足时执行
语法规则:
| 要点 | 说明 |
|---|---|
if | 必须有,是条件判断的入口 |
elif | 可选,可以有多个,是 else if 的缩写 |
else | 可选,最多一个,兜底分支 |
| 条件 | 任何能产生布尔值(True/False)的表达式 |
| 缩进 | Python 用缩进(通常 4 个空格)表示代码块,不用花括号 {} |
冒号 : | 每个分支条件后面必须加 : |
2.1.2 基础示例
score = 85
if score >= 90:
print("优秀")
elif score >= 80:
print("良好") # ← 命中这里
elif score >= 60:
print("及格")
else:
print("不及格")
2.1.3 条件表达式(三元运算符)
当只有两个分支且每个分支只有一条赋值语句时,可以简写:
# 标准写法
if age >= 18:
status = "成年"
else:
status = "未成年"
# 三元运算符简写
status = "成年" if age >= 18 else "未成年"
2.1.4 使用场景
| 场景 | 示例 |
|---|---|
| 成绩等级判定 | 根据分数范围输出 A/B/C/D |
| 用户权限判断 | 管理员/普通用户/游客看到不同菜单 |
| 数据校验 | 检查输入是否合法,给出不同提示 |
| 游戏逻辑 | 血量 > 0 继续游戏,否则 Game Over |
2.1.5 条件中的运算符
# 比较运算符
x == y # 等于
x != y # 不等于
x > y # 大于
x < y # 小于
x >= y # 大于等于
x <= y # 小于等于
# 逻辑运算符
a and b # 与:两个都为 True 才为 True
a or b # 或:至少一个为 True 就为 True
not a # 非:取反
# 成员运算符
x in [1, 2, 3] # x 是否在列表中
x not in "hello" # x 是否不在字符串中
综合示例:
age = 25
has_ticket = True
if age >= 18 and has_ticket:
print("可以入场")
elif age >= 18 and not has_ticket:
print("请先购票")
else:
print("未成年人需家长陪同")
2.2 模式匹配 match / case(Python 3.10+)
Python 3.10 引入了 match/case 语句,功能类似于其他语言的 switch/case,但更强大。
2.2.1 语法定义
match 目标值:
case 模式1:
代码块1
case 模式2:
代码块2
case _:
兜底代码块 # 相当于 else / default
语法规则:
| 要点 | 说明 |
|---|---|
match | 后面跟要被匹配的目标值(变量、表达式等) |
case | 每个分支定义一个匹配模式 |
_ | 通配符,匹配任何值,相当于 default / else,放在最后 |
| 无需 break | 匹配成功后自动跳出,不会"穿透"到下一个 case |
| 缩进 | 与 if/for/while 一样,用缩进表示代码块 |
2.2.2 基础示例 — 等值匹配
command = "start"
match command:
case "start":
print("启动程序")
case "stop":
print("停止程序")
case "pause":
print("暂停程序")
case _:
print(f"未知命令: {command}")
与 if/elif 的等价对比:
# if/elif 写法
if command == "start":
print("启动程序")
elif command == "stop":
print("停止程序")
elif command == "pause":
print("暂停程序")
else:
print(f"未知命令: {command}")
# match/case 写法(更简洁清晰)
match command:
case "start":
print("启动程序")
case "stop":
print("停止程序")
case "pause":
print("暂停程序")
case _:
print(f"未知命令: {command}")
2.2.3 多值匹配
一个 case 可以匹配多个值,用 | 分隔:
http_status = 404
match http_status:
case 200:
print("OK")
case 301 | 302:
print("重定向")
case 404:
print("未找到")
case 500 | 502 | 503:
print("服务器错误")
case _:
print("未知状态码")
2.2.4 带条件的匹配(Guard)
在 case 后面加 if 条件,实现更精细的匹配:
score = 85
match True:
case _ if score >= 90:
print("优秀")
case _ if score >= 80:
print("良好") # ← 命中
case _ if score >= 60:
print("及格")
case _:
print("不及格")
2.2.5 解构匹配(match/case 的独有能力)
match/case 比普通 switch 更强大,可以直接解构数据结构:
# 解构元组
point = (0, 5)
match point:
case (0, 0):
print("原点")
case (0, y):
print(f"在 Y 轴上,y={y}") # ← 命中
case (x, 0):
print(f"在 X 轴上,x={x}")
case (x, y):
print(f"普通点 ({x}, {y})")
# 解构列表
coords = [1, 2, 3]
match coords:
case [x]:
print(f"一维: {x}")
case [x, y]:
print(f"二维: ({x}, {y})")
case [x, y, z]:
print(f"三维: ({x}, {y}, {z})") # ← 命中
2.2.6 使用场景
| 场景 | 说明 |
|---|---|
| 菜单/命令分发 | 根据用户输入的命令执行不同操作 |
| HTTP 状态码处理 | 不同状态码对应不同处理逻辑 |
| 数据结构解构 | 根据数据的形状/内容执行不同分支 |
| 状态机 | 根据当前状态决定下一步行为 |
| 替代长串 if/elif | 多个等值判断时,比 if/elif 更清晰 |
2.2.7 match/case vs if/elif 选择建议
| 情况 | 推荐 |
|---|---|
| 简单的等值判断(3 个以上分支) | match/case |
| 需要解构数据结构 | match/case(if 做不到) |
| 复杂的范围/条件判断 | if/elif |
| 只有 2 个分支 | if/else 更简洁 |
| Python 版本 < 3.10 | 只能用 if/elif |
2.3 for 循环
for 循环用于遍历一个可迭代对象(如列表、字符串、元组、range 等),逐个取出元素进行处理。
2.3.1 语法定义
for 变量 in 可迭代对象:
循环体代码
语法规则:
| 要点 | 说明 |
|---|---|
for ... in | 固定语法,从可迭代对象中逐个取出元素 |
| 变量 | 每次循环自动赋值为当前取出的元素 |
| 可迭代对象 | 列表、元组、字符串、字典、range() 等 |
| 循环次数 | 由可迭代对象的元素个数决定,遍历完自动结束 |
2.3.2 基础示例
# 遍历列表
fruits = ["苹果", "香蕉", "橘子"]
for fruit in fruits:
print(fruit)
# 遍历字符串
for char in "Python":
print(char, end=" ") # 输出:P y t h o n
# 遍历字典
scores = {"张三": 85, "李四": 92, "王五": 78}
for name, score in scores.items():
print(f"{name}: {score}分")
2.3.3 range() 函数
range() 常与 for 搭配,用于生成数字序列,控制循环次数。
range(stop) # 生成 0 到 stop-1
range(start, stop) # 生成 start 到 stop-1
range(start, stop, step) # 指定步长
# 循环 5 次
for i in range(5):
print(i) # 0, 1, 2, 3, 4
# 指定范围
for i in range(1, 6):
print(i) # 1, 2, 3, 4, 5
# 指定步长(偶数)
for i in range(0, 10, 2):
print(i) # 0, 2, 4, 6, 8
# 倒序
for i in range(5, 0, -1):
print(i) # 5, 4, 3, 2, 1
2.3.4 使用场景
| 场景 | 示例 |
|---|---|
| 遍历数据容器 | 逐个处理列表、字典中的元素 |
| 固定次数循环 | 重复执行 N 次操作 |
| 生成数字序列 | 配合 range() 产生序号、编号 |
| 嵌套循环 | 打印表格、乘法表、图形 |
2.4 while 循环
while 循环在条件为 True 时持续执行,适合不确定循环次数、但知道终止条件的场景。
2.4.1 语法定义
while 条件:
循环体代码
语法规则:
| 要点 | 说明 |
|---|---|
| 条件 | 每次循环前都会判断,为 True 则继续,为 False 则退出 |
| 死循环 | 如果条件永远为 True,循环永远不会结束(需配合 break) |
| 更新变量 | 循环体内通常要有改变条件的操作,否则容易死循环 |
2.4.2 基础示例
# 计数循环
count = 1
while count <= 5:
print(f"第 {count} 次")
count += 1 # 每次加 1,最终使条件变为 False
# 用户输入验证
password = ""
while password != "123456":
password = input("请输入密码: ")
print("登录成功!")
2.4.3 while True 无限循环
while True:
cmd = input("请输入命令(输入 q 退出): ")
if cmd == "q":
break # 满足条件时跳出循环
print(f"执行命令: {cmd}")
2.4.4 使用场景
| 场景 | 示例 |
|---|---|
| 不确定循环次数 | 持续读取用户输入,直到输入特定值 |
| 菜单系统 | 反复显示菜单,等待用户选择 |
| 游戏主循环 | 持续运行直到玩家退出 |
| 轮询/等待 | 等待某个条件成立(如文件就绪、网络连通) |
2.5 for 与 while 对比
| 对比项 | for 循环 | while 循环 |
|---|---|---|
| 适用场景 | 已知遍历目标或循环次数 | 只知道终止条件,不知道次数 |
| 遍历能力 | 直接遍历容器元素 | 需要手动管理索引 |
| 死循环风险 | 低(遍历完自动结束) | 高(条件不变就永远循环) |
| 典型用法 | for i in range(10): | while count < 100: |
# 同样的功能,两种写法对比
# for:遍历列表(推荐)
names = ["张三", "李四", "王五"]
for name in names:
print(name)
# while:需要手动管理索引
names = ["张三", "李四", "王五"]
i = 0
while i < len(names):
print(names[i])
i += 1
2.6 循环控制语句 break / continue / pass
这三个语句用于在循环内部精细控制执行流程。
2.6.1 break — 立即终止整个循环
# 在 1-10 中找到第一个能被 7 整除的数
for i in range(1, 11):
if i % 7 == 0:
print(f"找到了: {i}")
break # 找到后立刻退出循环,不再继续
执行流程:
i=1 → 不满足 → i=2 → 不满足 → ... → i=7 → 满足 → print → break → 循环结束
2.6.2 continue — 跳过本次,进入下一次
# 打印 1-10 中的奇数(跳过偶数)
for i in range(1, 11):
if i % 2 == 0:
continue # 跳过本次循环的剩余代码,直接进入下一次
print(i) # 只输出 1, 3, 5, 7, 9
执行流程:
i=1 → 奇数 → print(1)
i=2 → 偶数 → continue → 跳到 i=3
i=3 → 奇数 → print(3)
...
2.6.3 pass — 空操作占位符
pass 什么都不做,仅用于保持语法完整(某些地方必须有代码才能运行)。
# 场景一:暂时未实现的分支
for i in range(10):
if i < 5:
pass # TODO: 以后再补充逻辑
else:
print(i)
# 场景二:定义空类或空函数
class MyFutureClass:
pass # 以后再填充内容
def my_future_function():
pass # 以后再填充内容
2.6.4 break 与 continue 对比
| 对比项 | break | continue |
|---|---|---|
| 作用 | 终止整个循环 | 跳过本次循环 |
| 后续执行 | 不再执行任何迭代 | 继续下一次迭代 |
| 使用场景 | 找到目标后立刻停止 | 过滤掉不需要的元素 |
# break:找到第一个偶数就停止
for n in [1, 3, 5, 4, 7, 8]:
if n % 2 == 0:
print(f"找到偶数: {n}")
break
# 输出:找到偶数: 4
# continue:跳过所有偶数
for n in [1, 3, 5, 4, 7, 8]:
if n % 2 == 0:
continue
print(n, end=" ")
# 输出:1 3 5 7
2.7 while...else / for...else
Python 独有的语法:循环正常结束(没有被 break)时,执行 else 块。
# for...else:检查列表中是否有负数
numbers = [1, 5, 8, 10, 15]
for n in numbers:
if n < 0:
print("发现负数!")
break
else:
# 循环没有被 break 中断时执行
print("所有数字都是正数")
| 情况 | else 是否执行 |
|---|---|
| 循环正常结束 | 执行 |
循环被 break 中断 | 不执行 |
2.8 嵌套循环与 99 乘法表
for i in range(1, 10): # 外层循环 - 控制行
for j in range(1, i + 1): # 内层循环 - 控制列
print(f"{j} x {i} = {j * i}", end="\t")
print() # 换行
知识点拆解:
| 知识点 | 说明 |
|---|---|
range(start, end) | 生成从 start 到 end-1 的整数序列 |
end="\t" | print() 默认以换行结尾,end="\t" 改为以制表符结尾 |
| 嵌套循环 | 外层循环每执行一次,内层循环完整执行一轮 |
输出效果:
1 x 1 = 1
1 x 2 = 2 2 x 2 = 4
1 x 3 = 3 2 x 3 = 6 3 x 3 = 9
...
2.9 综合案例:猜数字游戏
这是一个综合了 random、while、if/elif/else、try/except 的小游戏。
import random
target_number = random.randint(1, 100) # 生成 1-100 的随机整数
while True:
try:
user_guess = int(input("请输入你猜的数字: "))
except ValueError:
print("输入无效,请输入一个整数!")
continue
if user_guess > target_number:
print("猜大了!再试一次。")
elif user_guess < target_number:
print("猜小了!再试一次。")
else:
print(f"恭喜你!猜对了,答案就是 {target_number}!")
break
涉及知识点:
| 知识点 | 说明 |
|---|---|
random.randint(a, b) | 生成 [a, b] 范围内的随机整数 |
while True | 无限循环,配合 break 退出 |
if / elif / else | 条件分支判断 |
try / except ValueError | 捕获用户输入非数字时的异常 |
break | 跳出当前循环 |
continue | 跳过本次循环,进入下一次 |
第三章:数据容器(08-18)
3.1 列表 list
列表是 Python 中最常用的数据容器,有序、可修改、可重复、可存储不同类型。
3.1.1 定义与基本操作
s = [100, 120, "hello", "o", 'l', 90, 9, True]
| 操作 | 语法 | 说明 |
|---|---|---|
| 访问元素 | s[0] | 通过索引获取,索引从 0 开始 |
| 修改元素 | s[1] = 150 | 直接赋值修改 |
| 删除元素 | del s[1] | 删除指定索引的元素 |
| 遍历 | for item in s: | 逐个取出元素 |
| 切片 | s[0:2:1] | [起始:结束:步长] |
切片详解:
l = ["A", "B", "C", "D", "E", "F", "G"]
l[0:2:1] # ['A', 'B'] 从索引 0 到 1(不含 2),步长 1
l[:2] # ['A', 'B'] 省略起始默认为 0
l[:5:2] # ['A', 'C', 'E'] 从 0 到 4,步长 2
3.1.2 列表常用方法
s = [53, 23, 76, 100, 10, 32]
| 方法 | 说明 | 示例 |
|---|---|---|
append(x) | 在末尾添加元素 | s.append(900) |
insert(i, x) | 在指定位置插入 | s.insert(0, 111) |
remove(x) | 移除第一个匹配的值 | s.remove(23) |
pop(i) | 删除并返回指定索引元素 | s.pop(0) |
sort() | 升序排序 | s.sort() |
reverse() | 反转列表 | s.reverse() |
3.2 字符串常用方法
s = " hello-Python-Hello-World "
| 方法 | 说明 | 示例结果 |
|---|---|---|
find(sub) | 查找子串首次出现的索引,找不到返回 -1 | s.find("-") → 6 |
count(sub) | 统计子串出现次数 | s.count("o") → 3 |
upper() | 全部转大写 | "HELLO-PYTHON..." |
lower() | 全部转小写 | " hello-python..." |
split(sep) | 按分隔符截取,返回列表 | s.split("-") → [' hello', 'Python', ...] |
strip() | 去除两端空白字符 | "hello-Python-Hello-World" |
replace(old, new) | 替换字符串 | s.replace("-", "_") |
startswith(prefix) | 是否以指定子串开头 | s.startswith("hello") → False(前面有空格) |
邮箱验证案例:
email = input("请输入一个邮箱地址: ")
if email.count('@') == 1 and '.' in email:
print("邮箱格式正确")
else:
print("邮箱格式错误")
3.3 元组 tuple
元组是不可变的序列,创建后不能修改,只能查询。
3.3.1 定义与基本操作
t1 = (10, 20, 30, 40, 50, 30)
| 操作 | 语法 | 说明 |
|---|---|---|
| 索引访问 | t1[0] | 获取第一个元素 |
| 负索引 | t1[-1] | 获取最后一个元素 |
| 切片 | t1[0:2:1] | 与列表切片语法一致 |
count(x) | 统计元素出现次数 | t1.count(30) → 2 |
index(x) | 查找元素首次出现的索引 | t1.index(30) → 2 |
定义单元素元组时必须加逗号:
t2 = (100,) # 注意末尾的逗号
print(type(t2)) # <class 'tuple'>
3.3.2 元组组包与解包
# 组包:将多个值打包成元组
t1 = (10, 20, 30, 40, 50, 60, 99, 100)
t2 = 10, 20, 30, 40 # 省略括号也可以
# 解包:将元组元素分别赋值给多个变量
a, b, c, d = t2
# * 收集剩余的所有元素
e, f, *other, g = t1
print(other) # [30, 40, 50, 60, 99]
# 经典用法:交换两个变量
a1, b1 = 10, 20
a1, b1 = b1, a1 # a1=20, b1=10
3.4 集合 set
集合是无序、不重复的数据容器,天然支持去重和集合运算。
3.4.1 定义与基本操作
s1 = {"hello", 5, 243, 12, 0, 5} # 自动去重,5 只会出现一次
s2 = set() # 定义空集合(不能用 {},那是空字典)
| 方法 | 说明 |
|---|---|
add(x) | 添加元素 |
remove(x) | 移除指定元素 |
pop() | 随机删除并返回一个元素 |
clear() | 清空集合 |
3.4.2 集合运算
s5 = {"A", "B", "C", "D", "E", "F", "G"}
s6 = {"A", "B", "C", "D"}
| 运算 | 方法 | 运算符 | 说明 |
|---|---|---|---|
| 差集 | s5.difference(s6) | s5 - s6 | 在 s5 但不在 s6 中的元素 |
| 并集 | s5.union(s6) | s5 | s6 | 两个集合的所有元素(去重) |
| 交集 | s5.intersection(s6) | s5 & s6 | 两个集合共有的元素 |
课程选修案例:
football_set = {"王林", "曾牛", "徐立国", ...}
basketball_set = {"张铁", "王林", "曾牛", ...}
# 同时选修足球和篮球的学生
both = football_set & basketball_set
# 选修足球但没选修篮球的学生
only_football = football_set - basketball_set
# 所有选修了任意课程的学生
all_students = football_set | basketball_set
3.5 字典 dict
字典存储键值对(key: value),通过 key 快速查找 value。
核心特点:
- key 不能重复(重复会被覆盖)
- key 必须是不可变类型(字符串、数字、元组可以;列表不行)
- value 可以是任意类型
- Python 3.7+ 字典保持插入顺序
3.5.1 定义与基本操作
dict1 = {"王林": 456, "李慕婉": 234, "韩立": 542, "徐立国": 210}
| 操作 | 语法 | 说明 |
|---|---|---|
| 取值 | dict1["王林"] | key 不存在会报错 KeyError |
| 安全取值 | dict1.get("王林") | key 不存在返回 None(不报错) |
| 修改 | dict1["王林"] = 700 | key 存在则覆盖 |
| 添加 | dict1["新key"] = value | key 不存在则新增 |
| 删除 | del dict1["key"] | 删除指定键值对 |
| 弹出 | dict1.pop("key") | 删除并返回 value |
3.5.2 遍历
# 遍历所有键值对(最常用)
for k, v in dict1.items():
print(f"key为{k}; 值为{v}")
# 只遍历 key
for k in dict1.keys():
print(k)
# 只遍历 value
for v in dict1.values():
print(v)
3.6 综合案例
学生成绩管理系统
使用列表嵌套元组存储数据,综合运用循环、解包、格式化输出:
students = [
("S001", "王林", 85, 92, 78),
("S002", "李嘉婧", 92, 88, 95),
...
]
# 元组解包提取数据
for stu in students:
sid, name, chinese, math, english = stu
total = chinese + math + english
avg = total / 3
print(f"{sid:<6} {name:<6} {chinese:<6} {math:<6} {english:<6} {total:<6} {avg:.2f}")
购物车管理系统
使用字典嵌套字典实现完整的增删改查:
shopping_cart = {}
# 结构: { "商品名称": {"price": 价格, "quantity": 数量} }
# 添加商品
shopping_cart[name] = {"price": price, "quantity": quantity}
# 格式化输出对齐
print(f"{'商品名称':<15} {'商品价格':<15} {'商品数量':<10}")
print(f"{name:<15} ¥{info['price']:<14.2f} {info['quantity']:<10}")
3.7 列表推导式(List Comprehension)
列表推导式是 Python 最具特色的语法之一,用一行代码从已有序列生成新列表。
基本语法
# 语法:[表达式 for 变量 in 可迭代对象 if 条件]
# 传统写法:生成 1~10 的平方列表
squares = []
for x in range(1, 11):
squares.append(x ** 2)
# 列表推导式:一行搞定
squares = [x ** 2 for x in range(1, 11)]
print(squares) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
带条件过滤
# 筛选偶数
evens = [x for x in range(1, 21) if x % 2 == 0]
print(evens) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 筛选长度大于 3 的字符串
words = ["hi", "hello", "ok", "python", "yes"]
long_words = [w for w in words if len(w) > 3]
print(long_words) # ['hello', 'python']
if-else 三元表达式
# 偶数标记 "E",奇数标记 "O"
labels = ["E" if x % 2 == 0 else "O" for x in range(1, 6)]
print(labels) # ['O', 'E', 'O', 'E', 'O']
# 成绩评级
scores = [88, 55, 72, 93, 41]
grades = ["及格" if s >= 60 else "不及格" for s in scores]
print(grades) # ['及格', '不及格', '及格', '及格', '不及格']
嵌套推导式
# 展平二维列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 生成坐标组合
coords = [(x, y) for x in range(3) for y in range(3) if x != y]
print(coords) # [(0,1),(0,2),(1,0),(1,2),(2,0),(2,1)]
字典推导式 & 集合推导式
# 字典推导式
names = ["alice", "bob", "charlie"]
name_lengths = {name: len(name) for name in names}
print(name_lengths) # {'alice': 5, 'bob': 3, 'charlie': 7}
# 集合推导式(自动去重)
numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in numbers}
print(unique_squares) # {1, 4, 9, 16}
推导式 vs map/filter 对比
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 筛选偶数并求平方
# 推导式(推荐,更直观)
result = [x ** 2 for x in numbers if x % 2 == 0]
# map + filter(函数式风格)
result = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
面试提示: 列表推导式比等价的
map+filter更快(因为不需要函数调用),且可读性更好。
3.8 深拷贝与浅拷贝(面试高频)
Python 中赋值只是传递引用,拷贝分为浅拷贝和深拷贝,区别在于是否递归复制嵌套对象。
赋值 vs 浅拷贝 vs 深拷贝
import copy
original = [[1, 2, 3], [4, 5, 6]]
# 赋值:只是多了一个引用,完全共享
assignment = original
# 浅拷贝:复制外层容器,内层嵌套对象仍是引用
shallow = copy.copy(original)
# 等价写法:
shallow2 = original[:] # 列表切片
shallow3 = list(original) # list() 构造
shallow4 = original.copy() # .copy() 方法
# 深拷贝:递归复制所有层级
deep = copy.deepcopy(original)
关键区别:修改嵌套元素
import copy
original = [[1, 2], [3, 4]]
shallow = copy.copy(original)
deep = copy.deepcopy(original)
# 修改外层元素
original.append([5, 6])
print(shallow) # [[1, 2], [3, 4]] ← 浅拷贝不受影响
print(deep) # [[1, 2], [3, 4]] ← 深拷贝不受影响
# 修改内层嵌套元素
original[0][0] = 999
print(shallow) # [[999, 2], [3, 4]] ← 浅拷贝跟着变了!内层是共享引用
print(deep) # [[1, 2], [3, 4]] ← 深拷贝不受影响
内存图解
原始对象 original = [[1,2], [3,4]]
┌──────────────┐
│ 外层列表 ID_A │
│ [ref_B, ref_C]│
└──────┬───────┘
┌─────────┴─────────┐
┌────▼────┐ ┌─────▼────┐
│ [1, 2] │ │ [3, 4] │
│ ID_B │ │ ID_C │
└─────────┘ └──────────┘
浅拷贝 shallow = copy.copy(original)
→ 新建外层列表 ID_D,但内部仍引用 ID_B、ID_C
深拷贝 deep = copy.deepcopy(original)
→ 新建外层列表 ID_E + 新建内层列表 ID_F、ID_G(全部复制)
对比总结表
| 操作 | 语法 | 外层容器 | 嵌套对象 | 性能 |
|---|---|---|---|---|
| 赋值 | b = a | 共享引用 | 共享引用 | 最快(零开销) |
| 浅拷贝 | copy.copy(a) / a[:] / a.copy() | 复制新对象 | 共享引用 | 较快 |
| 深拷贝 | copy.deepcopy(a) | 复制新对象 | 递归复制 | 较慢(有递归开销) |
浅拷贝够用的场景
# 一维列表(无嵌套)浅拷贝即可
nums = [1, 2, 3, 4, 5]
nums_copy = nums[:]
nums_copy[0] = 999
print(nums) # [1, 2, 3, 4, 5] 不受影响
print(nums_copy) # [999, 2, 3, 4, 5]
必须用深拷贝的场景
import copy
# 嵌套结构(如二维列表、字典嵌套)
matrix = [[1, 2], [3, 4]]
matrix_copy = copy.deepcopy(matrix)
matrix_copy[0][0] = 999
print(matrix[0][0]) # 1(不受影响)
# 实际案例:配置模板
default_config = {
"database": {"host": "localhost", "port": 3306},
"features": ["auth", "logging"]
}
# 为不同环境创建独立配置
dev_config = copy.deepcopy(default_config)
prod_config = copy.deepcopy(default_config)
dev_config["database"]["host"] = "127.0.0.1"
prod_config["database"]["host"] = "10.0.0.1"
# 三者互不影响
面试陷阱题
a = [1, [2, 3]]
b = a.copy() # 浅拷贝
b[0] = 100 # 修改外层 → a 不受影响
b[1].append(4) # 修改内层 → a 也受影响!
print(a) # [1, [2, 3, 4]] ← 内层列表是共享的!
print(b) # [100, [2, 3, 4]]
记忆口诀: 浅拷贝只抄外壳,深拷贝连 internals 一起克隆。一维数据用切片,嵌套结构用 deepcopy。
第四章:函数(19-27)
4.1 函数基础
函数是一段可以反复调用的代码块,用于提高代码复用性。
定义语法:
def 函数名(参数列表):
"""文档字符串(可选)"""
函数体
return 返回值 # 可选
示例:
# 无参数函数
def out_line():
print("--------------")
# 带参数和返回值
def circle_area(r):
area = 3.14 * r * r
return area
# 带文档字符串
def rectangle_area(l, w):
"""
计算长方体面积
:param l: 长度
:param w: 宽度
:return: 长方体面积
"""
return l * w
函数练习:
# 计算三角形面积
def calculate_triangle_area(base, height):
return base * height / 2
# 计算元音字母个数
def count_vowels(text):
vowels = "aeiouAEIOU"
count = 0
for char in text:
if char in vowels:
count += 1
return count
# 分析成绩(返回多个值)
def analyze_scores(scores):
return max(scores), min(scores), round(sum(scores) / len(scores), 1)
4.2 函数进阶
4.2.1 变量作用域
num = 100 # 全局变量
def circle_area(r):
pi = 3.14 # 局部变量,函数外部不可访问
print("函数内部", num) # 可以读取全局变量
return pi * r * r
| 作用域 | 说明 |
|---|---|
| 全局变量 | 定义在函数外部,所有函数都能读取 |
| 局部变量 | 定义在函数内部,只在函数内有效 |
4.2.2 关键字参数
def reg_stu(name, age, gender, city):
print(f"姓名:{name}, 年龄:{age}, 性别:{gender}, 城市:{city}")
# 关键字参数:可以不按顺序,但位置参数必须在关键字参数之前
reg_stu(name="张三", age=18, gender="男", city="北京")
reg_stu("赵四", 28, gender="男", city="上海") # 混合使用
4.2.3 不定长参数 *args 和 **kwargs(面试必考)
核心概念:
| 参数 | 类型 | 收集内容 | 数据结构 |
|---|---|---|---|
*args | 位置参数 | 所有未匹配的位置参数 | tuple(元组) |
**kwargs | 关键字参数 | 所有未匹配的关键字参数 | dict(字典) |
基础用法:
def demo(*args, **kwargs):
print(f"args = {args}") # 元组
print(f"kwargs = {kwargs}") # 字典
demo(1, 2, "hello", name="Bob", score=99.5)
# args = (1, 2, 'hello')
# kwargs = {'name': 'Bob', 'score': 99.5}
参数定义顺序规则(面试常考):
# 正确的参数顺序:
def func(普通参数, *args, 关键字参数=默认值, **kwargs):
pass
# 示例
def register(name, *hobbies, city="未知", **extra):
print(f"姓名: {name}")
print(f"爱好: {hobbies}") # 元组
print(f"城市: {city}")
print(f"其他: {extra}") # 字典
register("张三", "篮球", "音乐", city="北京", age=20)
# 姓名: 张三
# 爱好: ('篮球', '音乐')
# 城市: 北京
# 其他: {'age': 20}
参数解包(调用时):
def add(a, b, c):
return a + b + c
# 列表/元组解包为位置参数
nums_list = [1, 2, 3]
print(add(*nums_list)) # 6 等价于 add(1, 2, 3)
nums_tuple = (10, 20, 30)
print(add(*nums_tuple)) # 60
# 字典解包为关键字参数
params = {"a": 1, "b": 2, "c": 3}
print(add(**params)) # 6 等价于 add(a=1, b=2, c=3)
实际应用场景:
# 场景一:通用日志函数
def log(level, message, *args, **kwargs):
"""支持格式化参数的日志"""
if args:
message = message % args
if kwargs:
message = message.format(**kwargs)
print(f"[{level}] {message}")
log("INFO", "用户 %s 登录成功", "张三")
log("WARN", "磁盘使用率 {pct}%", pct=85)
# 场景二:装饰器中转发参数
def timer(func):
def wrapper(*args, **kwargs):
import time
start = time.time()
result = func(*args, **kwargs) # 原样转发
print(f"{func.__name__} 耗时 {time.time() - start:.2f}s")
return result
return wrapper
# 场景三:计算任意数量参数的和
def flexible_sum(*args):
"""接收任意数量的数字并求和"""
return sum(args)
print(flexible_sum(1, 2, 3)) # 6
print(flexible_sum(10, 20, 30, 40)) # 100
只有关键字参数 / 只有关置参数(Python 3.8+):
# * 后面的参数必须用关键字方式传递
def connect(host, port, *, timeout=30, retry=3):
print(f"连接 {host}:{port},超时={timeout},重试={retry}")
connect("localhost", 3306) # OK
connect("localhost", 3306, timeout=60) # OK
# connect("localhost", 3306, 60) # TypeError!
# / 前面的参数只能用位置方式传递
def power(x, /, n=2):
return x ** n
power(3) # OK → 9
power(3, 3) # OK → 27
# power(x=3) # TypeError! x 不能用关键字
4.2.4 综合案例:订单金额计算
def calculate_order_total(products, coupon_discount=0, points=0, shipping_fee=0):
total_price = sum(item['price'] * item['quantity'] for item in products)
# 优惠券:满5000可用,不超过商品总价
valid_coupon = min(coupon_discount, total_price) if total_price >= 5000 else 0
# 积分:满5000可用,100积分=1元,整百抵扣
points_money = (points // 100) * 1 if total_price >= 5000 else 0
final_amount = total_price - valid_coupon - points_money + shipping_fee
return {"商品总价": total_price, "应付总额": max(0, final_amount), ...}
4.3 Lambda 匿名函数
Lambda 是一种简洁的匿名函数,只能包含一个表达式。
语法:
lambda 参数: 表达式
各种参数形式:
# 无参数
say_hello = lambda: print("Hello!")
# 默认参数
power = lambda x, n=2: x ** n
# 不定长参数
sum_all = lambda *args: sum(args)
核心应用场景 — 配合高阶函数:
data_list = [1, 5, 2, 8, 3]
# map(): 对每个元素进行操作
doubled = list(map(lambda x: x * 2, data_list)) # [2, 10, 4, 16, 6]
# filter(): 过滤元素
filtered = list(filter(lambda x: x > 3, data_list)) # [5, 8]
# sorted(): 自定义排序
students = [("张三", 88), ("李四", 95), ("王五", 72)]
sorted_students = sorted(students, key=lambda s: s[1], reverse=True)
# [("李四", 95), ("张三", 88), ("王五", 72)]
4.4 递归
递归是函数在内部调用自身,必须有终结点,否则会无限递归导致栈溢出。
def jc(n):
"""计算 n 的阶乘"""
if n == 1: # 终结点(基准情况)
return 1
else:
return n * jc(n - 1) # 递归调用
print(jc(10)) # 3628800
递归三要素:
- 终结点(base case):什么时候停止递归
- 递归调用:函数调用自身
- 递进关系:每次调用都向终结点靠近
4.5 类型注解
类型注解不影响运行,但能提高代码可读性和 IDE 提示。
变量类型注解:
a: int = 695
score: float = 98.5
hobby: str = "Python"
names: list[str] = ["A", "C", "E"]
phones: set[str] = {"13309091111"}
options: dict[str, int] = {"count": 0, "total": 0}
goods: tuple[str, int, int] = ("手机", 5999, 1)
函数类型注解:
def calc(scores: list[int]) -> float:
"""计算平均分"""
return sum(scores) / len(scores)
def calc_data(scores: list[int]) -> tuple[int, int, float]:
"""返回 (最高分, 最低分, 平均分)"""
return max(scores), min(scores), sum(scores) / len(scores)
4.6 装饰器(Decorator)
装饰器是 Python 的高级特性,用于在不修改原函数代码的前提下,给函数增加额外功能。本质是一个接收函数作为参数、并返回新函数的高阶函数。
4.6.1 语法定义
def 装饰器函数(原函数):
def 包装函数(*args, **kwargs):
# 调用前的额外操作
result = 原函数(*args, **kwargs)
# 调用后的额外操作
return result
return 包装函数
@装饰器函数
def 被装饰的函数():
pass
@装饰器函数 是语法糖,等价于 被装饰的函数 = 装饰器函数(被装饰的函数)。
4.6.2 基础示例 — 计时装饰器
import time
def timer(func):
"""计算函数执行耗时的装饰器"""
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 执行耗时: {end - start:.4f} 秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "完成"
slow_function()
# 输出:slow_function 执行耗时: 1.0012 秒
4.6.3 带参数的装饰器
def repeat(n):
"""让函数重复执行 n 次"""
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(n):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def say_hello(name):
print(f"Hello, {name}!")
say_hello("张三")
# Hello, 张三!
# Hello, 张三!
# Hello, 张三!
4.6.4 常用内置装饰器
| 装饰器 | 说明 | 使用场景 |
|---|---|---|
@staticmethod | 静态方法,不需要 self 或 cls | 工具函数,与实例/类无关 |
@classmethod | 类方法,第一个参数是 cls | 工厂方法、访问类属性 |
@property | 将方法变成属性访问 | getter/setter 封装 |
@functools.lru_cache | 缓存函数返回值 | 递归、重复计算优化 |
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
"""带缓存的斐波那契,避免重复计算"""
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(100)) # 瞬间完成,因为有缓存
4.6.5 使用场景
| 场景 | 说明 |
|---|---|
| 日志记录 | 自动记录函数调用信息 |
| 性能计时 | 统计函数执行耗时 |
| 权限校验 | 调用前检查用户权限 |
| 缓存结果 | 避免重复计算(如 @lru_cache) |
| 重试机制 | 失败后自动重试 N 次 |
4.7 迭代器与生成器
4.7.1 可迭代对象与迭代器
| 概念 | 定义 | 判断方式 |
|---|---|---|
| 可迭代对象(Iterable) | 实现了 __iter__() 方法的对象,可以被 for 循环遍历 | isinstance(obj, Iterable) |
| 迭代器(Iterator) | 实现了 __iter__() 和 __next__() 方法的对象,可以逐个取值直到耗尽 | isinstance(obj, Iterator) |
from collections.abc import Iterable, Iterator
# 列表是可迭代对象,但不是迭代器
lst = [1, 2, 3]
print(isinstance(lst, Iterable)) # True
print(isinstance(lst, Iterator)) # False
# 调用 iter() 后变成迭代器
it = iter(lst)
print(isinstance(it, Iterator)) # True
print(next(it)) # 1
print(next(it)) # 2
print(next(it)) # 3
# print(next(it)) # 抛出 StopIteration
常见可迭代对象: list、tuple、str、dict、set、range()、文件对象
4.7.2 生成器函数(yield)
生成器是一种特殊的迭代器,用 yield 关键字定义,按需生成值,节省内存。
def count_up(n):
"""从 1 数到 n"""
i = 1
while i <= n:
yield i
i += 1
# 生成器不会一次性计算所有值,而是每次调用 next() 时才生成一个
gen = count_up(5)
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
# 也可以用 for 循环遍历
for num in count_up(5):
print(num, end=" ") # 1 2 3 4 5
生成器 vs 列表对比:
# 列表:一次性占用全部内存
big_list = [x ** 2 for x in range(1000000)] # 立即分配 100 万个元素的内存
# 生成器:按需生成,几乎不占内存
big_gen = (x ** 2 for x in range(1000000)) # 生成器表达式,几乎不占内存
| 对比项 | 列表 | 生成器 |
|---|---|---|
| 语法 | [x for x in range(n)] | (x for x in range(n)) 或 yield |
| 内存 | 一次性加载全部数据 | 按需生成,占用极小 |
| 取值 | 可索引 lst[0] | 只能逐个 next() |
| 遍历 | 可多次遍历 | 只能遍历一次(耗尽即空) |
| 适用场景 | 数据量小、需要随机访问 | 数据量大、只需顺序访问 |
4.7.3 生成器的典型应用
# 读取大文件(不会一次性加载到内存)
def read_large_file(file_path):
with open(file_path, "r", encoding="utf-8") as f:
for line in f:
yield line.strip()
for line in read_large_file("big_data.txt"):
print(line)
# 无限序列
def infinite_counter(start=0):
while True:
yield start
start += 1
counter = infinite_counter()
print(next(counter)) # 0
print(next(counter)) # 1
print(next(counter)) # 2
4.8 常用内置函数速查
4.8.1 类型与转换
| 函数 | 说明 | 示例 |
|---|---|---|
type(obj) | 返回对象的类型 | type(123) → <class 'int'> |
isinstance(obj, cls) | 判断对象是否是指定类型的实例 | isinstance(123, int) → True |
int(x) | 转换为整数 | int("42") → 42 |
float(x) | 转换为浮点数 | float("3.14") → 3.14 |
str(x) | 转换为字符串 | str(100) → "100" |
bool(x) | 转换为布尔值 | bool(0) → False |
list(x) | 转换为列表 | list("abc") → ['a','b','c'] |
tuple(x) | 转换为元组 | tuple([1,2,3]) → (1,2,3) |
set(x) | 转换为集合 | set([1,1,2]) → {1,2} |
dict(x) | 转换为字典 | dict([("a",1),("b",2)]) → {"a":1,"b":2} |
4.8.2 数学与序列操作
| 函数 | 说明 | 示例 |
|---|---|---|
abs(x) | 绝对值 | abs(-5) → 5 |
round(x, n) | 四舍五入到 n 位小数 | round(3.1415, 2) → 3.14 |
max(...) | 最大值 | max(1,5,3) → 5 |
min(...) | 最小值 | min([2,7,4]) → 2 |
sum(iterable) | 求和 | sum([1,2,3]) → 6 |
len(obj) | 返回元素个数 | len("hello") → 5 |
pow(base, exp) | 幂运算 | pow(2, 10) → 1024 |
divmod(a, b) | 返回商和余数的元组 | divmod(7, 3) → (2, 1) |
4.8.3 序列操作
| 函数 | 说明 | 示例 |
|---|---|---|
sorted(iterable) | 排序,返回新列表 | sorted([3,1,2]) → [1,2,3] |
reversed(seq) | 反转,返回迭代器 | list(reversed([1,2,3])) → [3,2,1] |
enumerate(iterable) | 同时获取索引和值 | for i, v in enumerate(["a","b"]): |
zip(*iterables) | 将多个序列打包成元组 | zip([1,2], ["a","b"]) → (1,"a"),(2,"b") |
range(start, stop, step) | 生成数字序列 | range(0, 10, 2) → 0,2,4,6,8 |
slice(start, stop) | 切片对象 | s = slice(0, 3); lst[s] |
# enumerate 示例
fruits = ["苹果", "香蕉", "橘子"]
for i, fruit in enumerate(fruits, start=1):
print(f"{i}. {fruit}")
# 1. 苹果
# 2. 香蕉
# 3. 橘子
# zip 示例
names = ["张三", "李四", "王五"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}分")
4.8.4 函数式编程
| 函数 | 说明 | 示例 |
|---|---|---|
map(func, iterable) | 对每个元素应用函数 | list(map(str, [1,2,3])) → ['1','2','3'] |
filter(func, iterable) | 过滤满足条件的元素 | list(filter(lambda x: x>0, [-1,2,-3])) → [2] |
sorted(iterable, key=func) | 按自定义规则排序 | sorted(students, key=lambda s: s[1]) |
4.8.5 其他常用
| 函数 | 说明 | 示例 |
|---|---|---|
print(*args, sep, end) | 输出到控制台 | print("a", "b", sep="-") → a-b |
input(prompt) | 读取键盘输入(返回 str) | name = input("姓名: ") |
id(obj) | 返回对象的内存地址 | id(x) |
hash(obj) | 返回对象的哈希值 | hash("hello") |
callable(obj) | 判断对象是否可调用 | callable(print) → True |
help(obj) | 显示帮助文档 | help(len) |
dir(obj) | 列出对象的所有属性和方法 | dir(str) |
open(file, mode) | 打开文件 | open("data.txt", "r") |
第五章:模块与包(28-32)
5.1 模块的概念与导入方式
模块就是一个 .py 文件,里面可以包含函数、类、变量等,可以被其他文件导入使用。
五种导入方式:
# 1. 导入整个模块
import random
# 2. 给模块起别名
import random as rd
# 3. 从模块中导入指定功能
from random import randint
# 4. 导入模块中的所有功能(不推荐)
from random import *
# 5. 导入并给功能起别名
from random import randint as ri
5.2 __name__ 与 __all__
__name__:模块的身份证
if __name__ == "__main__":
# 只有直接运行此文件时才执行
# 被其他文件 import 时不会执行
print("测试代码")
| 场景 | __name__ 的值 |
|---|---|
| 直接运行文件 | "__main__" |
| 被其他文件导入 | 模块文件名(如 "my_function") |
__all__:导出白名单
__all__ = ["PI", "log_separator1", "log_separator2"]
当别人使用 from module import * 时,只有 __all__ 中列出的名字才能被导入。
5.3 包(Package)
包本质上就是一个包含 __init__.py 文件的文件夹,用于管理多个模块。
目录结构:
项目目录/
├── main.py # 主程序
└── my_package/ # 包
├── __init__.py # 包的标志文件
├── add.py # 模块
└── sub.py # 模块
四种导入方式:
# 1. import 包名.模块名
import my_package.add
result = my_package.add.add(10, 5)
# 2. from 包名 import 模块名
from my_package import add, sub
print(add.add(10, 5))
# 3. from 包名.模块名 import 功能名
from my_package.add import add
print(add(20, 30))
# 4. from 包名 import *(不推荐)
from my_package import *
附录:知识点速查表
数据容器对比
| 特性 | 列表 list | 元组 tuple | 集合 set | 字典 dict |
|---|---|---|---|---|
| 语法 | [1,2,3] | (1,2,3) | {1,2,3} | {"k":"v"} |
| 有序 | 是 | 是 | 否 | 是(3.7+) |
| 可修改 | 是 | 否 | 是 | 是 |
| 可重复 | 是 | 是 | 否 | key 不可重复 |
| 查找速度 | O(n) | O(n) | O(1) | O(1) |
| 典型用途 | 通用序列 | 不可变数据 | 去重/集合运算 | 键值映射 |
字符串格式化对比
| 方式 | 语法 | 推荐度 |
|---|---|---|
| % 占位符 | "name=%s" % name | 旧式,不推荐 |
format() | "name={}".format(name) | 兼容旧版本 |
| f-string | f"name={name}" | 最推荐 |
函数参数类型
| 参数类型 | 语法 | 说明 |
|---|---|---|
| 位置参数 | def f(a, b) | 按顺序传入 |
| 关键字参数 | f(a=1, b=2) | 按名称传入 |
| 默认参数 | def f(a, b=10) | 不传则用默认值 |
| 不定长位置 | def f(*args) | 接收为元组 |
| 不定长关键字 | def f(**kwargs) | 接收为字典 |