Part 3 语法进阶部分
1. 课件5:流程控制
程序执行的三种基本结构:
- 顺序结构(Sequential Structure)
代码按顺序从上到下执行。 - 选择结构(Selection Structure)
或称为分支结构
根据条件判断执行不同的代码块。 - 循环结构(Loop Structure)
根据条件重复执行代码块。
1.1. 顺序结构
顺序结构是程序中最基本的执行方式,代码按书写顺序逐行执行。
python
"""
示例:演示 Python 中顺序结构
包含演示:
- 顺序结构:程序从上到下依次执行代码。
运行:
python sequential_demo.py
作者:自动生成示例(中文注释)
"""
def sequential_demo():
print('--- 顺序结构示例 ---')
print('程序从上到下依次执行:')
# 第一步:变量赋值
a = 10
print('第一步:a = 10')
# 第二步:另一个赋值
b = 20
print('第二步:b = 20')
# 第三步:计算
c = a + b
print('第三步:c = a + b =', c)
# 第四步:输出结果
print('第四步:输出结果 c =', c)
print('顺序执行完成。')
def main():
sequential_demo()
if __name__ == '__main__':
main()
1.2. 选择结构
分支结构
根据条件成立预购,决定执行哪个代码块。
- 单分支结构(if语句)
- 双分支结构(if-else语句)
- 条件表达式(三元表达式)
- 多分支结构(if-elif-else语句)
- 嵌套分支结构
python
"""
示例:演示 Python 中分支结构
包含演示:
- if-elif-else 语句
- 条件表达式(三元运算符)
- 嵌套 if 语句
运行:
python branching_demo.py
作者:自动生成示例(中文注释)
"""
def if_elif_else_demo():
print('--- if-elif-else 示例 ---')
score = int(input('请输入成绩(0-100):'))
if score >= 90:
grade = 'A'
elif score >= 80:
grade = 'B'
elif score >= 70:
grade = 'C'
elif score >= 60:
grade = 'D'
else:
grade = 'F'
print(f'成绩 {score} 对应的等级:{grade}')
print()
def conditional_expression_demo():
print('--- 条件表达式示例 ---')
age = int(input('请输入年龄:'))
# 条件表达式:值1 if 条件 else 值2
status = '成年' if age >= 18 else '未成年'
print(f'年龄 {age}:{status}')
# 另一个示例
num = int(input('请输入一个数字:'))
result = '正数' if num > 0 else ('负数' if num < 0 else '零')
print(f'数字 {num} 是:{result}')
print()
def nested_if_demo():
print('--- 嵌套 if 示例 ---')
username = input('请输入用户名:')
password = input('请输入密码:')
if username == 'admin':
if password == '123456':
print('登录成功!')
else:
print('密码错误!')
else:
print('用户名不存在!')
print()
def main():
if_elif_else_demo()
conditional_expression_demo()
nested_if_demo()
if __name__ == '__main__':
main()
1.2.1. 补充
random模块
常配合选择结构使用,实现随机决策。
常用函数:
- randint(a, b):返回[a, b]范围内的随机整数。
- choice(seq):从非空序列seq中随机选择一个元素。
- shuffle(seq):将序列seq随机打乱。
- sample(population, k):从总体population中随机选择k个独立元素,返回列表。
1.3. 循环结构
循环结构用于重复执行代码块,直到满足特定条件。
两种基本语句:
- while循环
根据条件表达式的真假决定是否继续循环。
适用于循环次数不确定的情况。 - for循环
遍历序列(如列表、字符串、字典等)中的每个元素。
适用于已知循环次数的情况。 - 循环中的else子句
python特色
如果循环正常结束(非break跳出),则执行else块。 - range()函数
生成整数序列,常用于for循环。
支持start, stop, step参数。
语法:range(start, stop[, step])
python
"""
示例:演示 Python 中循环结构
包含演示:
- while 循环
- for 循环
- 循环控制:break, continue, pass
- 嵌套循环
运行:
python loops_demo.py
作者:自动生成示例(中文注释)
"""
def while_loop_demo():
print('--- while 循环示例 ---')
count = 1
while count <= 5:
print(f'计数:{count}')
count += 1
print()
def for_loop_demo():
print('--- for 循环示例 ---')
fruits = ['苹果', '香蕉', '橙子']
for fruit in fruits:
print(f'水果:{fruit}')
print()
# 遍历字符串
for char in 'Python':
print(f'字符:{char}')
print()
def break_continue_pass_demo():
print('--- break, continue, pass 示例 ---')
# break 示例
print('break 示例:遇到 3 时停止')
for i in range(1, 6):
if i == 3:
break
print(f'数字:{i}')
print()
# continue 示例
print('continue 示例:跳过 3')
for i in range(1, 6):
if i == 3:
continue
print(f'数字:{i}')
print()
# pass 示例
print('pass 示例:占位符')
for i in range(1, 4):
if i == 2:
pass # 不执行任何操作
print(f'处理:{i}')
print()
def nested_loops_demo():
print('--- 嵌套循环示例 ---')
for i in range(1, 4): # 外层循环
print(f'外层:{i}')
for j in range(1, 4): # 内层循环
print(f' 内层:{i},{j}')
print()
print()
def main():
while_loop_demo()
for_loop_demo()
break_continue_pass_demo()
nested_loops_demo()
if __name__ == '__main__':
main()
1.3.1. 循环控制与跳转语句
- break语句
立即终止循环,跳出循环体。 - continue语句
跳过当前循环迭代,进入下一次循环。 - pass语句
占位符语句,不执行任何操作。
用于需要语法上有代码但逻辑上不需要执行任何操作的场景。
1.3.2. 嵌套循环与优化
- 嵌套循环
在一个循环体内再包含另一个循环。
注意控制好循环变量,避免混淆。 - 循环优化技巧
尽量减少循环内部不必要的计算量
1.4. 进阶控制
用到的知识点在之后有讲
python
"""
示例:演示 Python 中其他控制结构
包含演示:
- 列表推导式
- 生成器表达式
- 异常处理与控制结构的结合
运行:
python advanced_control_demo.py
作者:自动生成示例(中文注释)
"""
def list_comprehension_demo():
print('--- 列表推导式示例 ---')
# 基本列表推导式
squares = [x**2 for x in range(1, 6)]
print('平方列表:', squares)
# 带条件的列表推导式
even_squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print('偶数平方列表:', even_squares)
# 嵌套列表推导式
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
print('乘法表:', matrix)
print()
def generator_expression_demo():
print('--- 生成器表达式示例 ---')
# 生成器表达式
gen = (x**2 for x in range(1, 6))
print('生成器对象:', gen)
print('转换为列表:', list(gen))
# 使用生成器节省内存
large_gen = (x for x in range(1000000) if x % 2 == 0)
print('大生成器(前10个):', [next(large_gen) for _ in range(10)])
print()
def exception_with_control_demo():
print('--- 异常处理与控制结构的结合示例 ---')
# 在循环中使用异常处理
numbers = ['1', '2', 'abc', '4', 'def']
valid_numbers = []
for item in numbers:
try:
num = int(item)
valid_numbers.append(num)
except ValueError:
print(f'跳过无效项:{item}')
print('有效数字列表:', valid_numbers)
print()
# 在列表推导式中使用异常处理(使用函数)
def safe_int(x):
try:
return int(x)
except ValueError:
return None
mixed_list = ['1', '2', 'abc', '4', 'def']
converted = [safe_int(x) for x in mixed_list if safe_int(x) is not None]
print('转换后的有效数字:', converted)
print()
def main():
list_comprehension_demo()
generator_expression_demo()
exception_with_control_demo()
if __name__ == '__main__':
main()
2. 列表与元组
python中两种最重要的线性数据结构
- 列表(List)
可变序列,支持增删改查操作。
使用方
括号[]定义,元素可为任意类型。 - 元组(Tuple)
不可变序列,一旦创建无法修改。
使用圆括号()定义,适用于存储不可变数据。
以及他们的共有重要操作 切片(Slicing)
python
"""
示例:演示 Python 中列表与元组
包含演示:
- 序列基础操作
- 列表操作(CRUD)
- 列表推导式
- 元组操作
- 生成器表达式
- 序列解包
- 切片操作
运行:
python lists_tuples_demo.py
作者:自动生成示例(中文注释)
"""
def sequence_basics():
print('--- 序列基础操作示例 ---')
lst = [3, 1, 4, 1, 5]
tup = (1, 2, 3, 4, 5)
print('列表:', lst)
print('元组:', tup)
print('len(lst) =', len(lst))
print('min(lst) =', min(lst))
print('max(lst) =', max(lst))
print('sum(lst) =', sum(lst))
print('3 in lst =', 3 in lst)
print('sorted(lst) =', sorted(lst)) # 不修改原列表
print('reversed(lst) =', list(reversed(lst))) # 转换为列表查看
print('enumerate(lst) =', list(enumerate(lst)))
print()
def list_operations():
print('--- 列表操作示例 ---')
# 创建
lst = []
print('空列表:', lst)
lst = [1, 2, 3]
print('初始列表:', lst)
# C
lst.append(4)
print('append(4):', lst)
lst.insert(1, 1.5)
print('insert(1, 1.5):', lst)
lst.extend([5, 6])
print('extend([5, 6]):', lst)
# R
print('lst[2] =', lst[2])
print('lst.index(3) =', lst.index(3))
print('lst.count(1) =', lst.count(1))
# U
lst[0] = 0
print('lst[0] = 0:', lst)
lst.sort()
print('sort():', lst)
lst.reverse()
print('reverse():', lst)
# D
popped = lst.pop()
print('pop() 返回:', popped, ';列表:', lst)
lst.remove(1.5)
print('remove(1.5):', lst)
del lst[0]
print('del lst[0]:', lst)
lst.clear()
print('clear():', lst)
print()
def list_comprehension_demo():
print('--- 列表推导式示例 ---')
# 基本
squares = [x**2 for x in range(1, 6)]
print('平方:', squares)
# 带条件
evens = [x for x in range(10) if x % 2 == 0]
print('偶数:', evens)
# 嵌套
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
print('乘法表:', matrix)
print()
def tuple_operations():
print('--- 元组操作示例 ---')
# 创建
tup = ()
print('空元组:', tup)
tup = (1, 2, 3)
print('元组:', tup)
single = (42,) # 单元素元组
print('单元素元组:', single)
# 不可变性
# tup[0] = 0 # 会报错
print('元组不可修改')
# 作为字典键
d = {(1, 2): 'tuple key'}
print('元组作为字典键:', d)
# 不可变性理解
nested = ([1, 2], 3)
nested[0].append(3) # 可以修改内部可变对象
nested[0].append([1,2])
print('嵌套元组,修改内部列表:', nested)
print()
def generator_expression_demo():
print('--- 生成器表达式示例 ---')
gen = (x**2 for x in range(1, 6))
print('生成器:', gen)
print('转换为列表:', list(gen))
# 节省内存
large_gen = (x for x in range(1000) if x % 2 == 0)
print('大生成器前5个:', [next(large_gen) for _ in range(5)])
print()
def unpacking_demo():
print('--- 序列解包示例 ---')
# 基本解包
x, y = 1, 2
print('x, y = 1, 2 -> x={}, y={}'.format(x, y))
x, y, z = (3, 4, 5)
print('x, y, z = (3,4,5) -> x={}, y={}, z={}'.format(x, y, z))
a, b, c = [1, 2, 3]
print('a, b, c = [1, 2, 3] -> a={}, b={}, c={}'.format(a, b, c))
# 通配符
x, *y, z = [1, 2, 3, 4, 5]
print('x, *y, z = [1,2,3,4,5] -> x={}, y={}, z={}'.format(x, y, z))
# 交换变量
m, n = 10, 20
print('交换前:m={}, n={}'.format(m, n))
m, n = n, m
print('交换后:m={}, n={}'.format(m, n))
print()
def slicing_demo():
print('--- 切片操作示例 ---')
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print('原列表:', lst)
# 基本切片
print('lst[2:5] =', lst[2:5])
print('lst[:3] =', lst[:3])
print('lst[7:] =', lst[7:])
print('lst[::2] =', lst[::2]) # 步长2
# 反向切片
print('lst[::-1] =', lst[::-1])
# 浅拷贝
copy_lst = lst[:]
copy_lst[0] = 99
print('浅拷贝后修改copy_lst[0]=99,原列表:', lst)
# 原地修改
lst[1:4] = [10, 20, 30]
print('lst[1:4] = [10,20,30] ->', lst)
print()
def main():
sequence_basics()
list_operations()
list_comprehension_demo()
tuple_operations()
generator_expression_demo()
unpacking_demo()
slicing_demo()
if __name__ == '__main__':
main()
2.1. 数据结构和序列基础
数据结构:组织和存储数据的方式
程序逻辑通过数据机构执行CRUD(增删改查)操作。
序列:有序的数据集合,支持索引和切片操作。
Python中包含列表、元组、字典、字符串等
-
有序序列:列表、元组、字符串
支持双向索引
正向从0开始,反向(指从尾开始)从-1开始
-
无序序列:字典、集合
-
可变性:
可变序列:列表、字典、集合
不可变序列:元组、字符串
共性方法:
- len():获取序列长度。
- min():获取序列中的最小值。
- max():获取序列中的最大值。
- sum():计算数值序列的总和。
- in运算符:检查元素是否在序列中存在。
- sorted()函数:返回序列的排序版本,不修改原序列。
- reversed()函数:返回序列的反转版本,不修改原序列。
- enumerate()函数:同时获取元素索引和值,常用于循环遍历。
2.2. 列表(List)
列表是包含在[]中的有序元素集合,支持动态修改。
Python中列表支持存储不同类型的元素。
内存本质:列表对象保存对元素对象的引用。
基本操作:
- C:
[]:创建空列表。[elem1, elem2, ...]:创建包含初始元素的列表。list(iterable):将可迭代对象转换为列表。append(elem):在列表末尾添加元素。insert(index, elem):在指定索引位置插入元素。
正向时,index范围为0到len(list)。
支持负索引。extend(iterable):将可迭代对象的元素添加到列表末尾。
- R:
- 通过索引访问元素,如
list[index]。 index(elem):返回元素首次出现的索引。count(elem):返回元素在列表中出现的次数。in运算符:检查元素是否在列表中存在。
- 通过索引访问元素,如
- U:
- 通过索引修改元素,如
list[index] = new_value。 sort():对列表进行原地排序。
原地指修改当前列表,不返回新列表。reverse():反转列表元素顺序。
- 通过索引修改元素,如
- D:
del语句:删除指定索引的元素。pop([index]):移除并返回指定索引的元素,默认移除最后一个。remove(elem):移除列表中首次出现的指定元素。clear():清空列表所有元素。- 易错环节:循环中删除列表元素,列表长度和索引会发生唯一,导致漏删
正确做法:遍历原列表的副本,或者从后向前删除。
2.2.1. 列表推导式
列表推导式是一种简洁的创建和操作列表的方式。
利用已有列表创建新列表。
语法:
[表达式 for 变量 in 可迭代对象 if 条件]
注意,以上结构也可以嵌套使用,形成多重循环或条件。
2.3. 元组(Tuple)
轻量的只读列表。
使用()定义,一旦创建不可修改。
实际上指的是这里的引用不能再指向其他对象,也不能添加或删除元素
创建注意事项:
- 单元素元组:需要在元素后加逗号,如
(elem,),否则被视为普通括号表达式。 - 空元组:使用
()创建。
优势:
- 不可变性:适用于存储不可修改的数据,提高数据安全性。
- 性能优势:由于不可变,元组在内存中占用更少空间,访问速度更快。
- 可作为字典键:由于不可变,元组可以用作字典的键,而列表不行。
深度理解不可变性:
指的是引用不能更改,但是如果引用指向的元素本身是可变的,那么可以修改该元素的内容。
2.3.1. 生成器表达式
生成器表达式是一种简洁的创建生成器的方式。
语法:
(表达式 for 变量 in 可迭代对象 if 条件)
返回生成器对象,按需计算元素。
惰性求值,节省内存。
适用场景:处理大数据集,避免一次性加载所有数据。
2.3.2. 序列解包
可以将序列中的值一次性存储到多个变量中
示例:
x, y = 1, 2:将元组(1, 2)解包到变量x和y中。- 通配符
*:用于捕获多余元素,形成列表。a, *b, c = [1, 2, 3, 4, 5]:a=1, b=[2, 3, 4], c=5
- 交换变量值:
a, b = b, a,无需临时变量。
2.4. 切片操作
序列的高级截取
语法:
L[start:stp:step]
核心特性:
浅拷贝(Shallow Copy):切片返回的是原序列的浅拷贝,修改切片不会影响原序列。
- start:起始索引,默认为0。
- stop:结束索引(不包含),默认为序列长度。
- step:步长,默认为1。可以为负数,实现反向切片。
支持省略参数:
L[:]:复制整个序列。L[start:]:从start到末尾。L[:stop]:从开头到stop(不包含)。L[::step]:整个序列,按step步长取值。
原地修改:
可以通过切片实现对序列的原地修改。
例如:L[start:stop] = iterable,将指定范围内的元素替换为新的可迭代对象的元素。
注意:如果步长不为1,替换的元素数量必须与切片长度相同。
3. 课件7:字典和集合
两种重要的非线性数据结构:
- 字典(Dictionary)
无序的键值对集合,支持快速查找和修改。
使用花括号{}定义,键必须是不可变类型。 - 集合(Set)
无序的不重复元素集合,支持数学集合操作。
使用花括号{}或set()函数定义。
python
"""
示例:演示 Python 中字典和集合
包含演示:
- 字典操作(CRUD)
- 集合操作(CRUD、数学运算)
- 性能对比(列表vs字典查找)
运行:
python dicts_sets_demo.py
作者:自动生成示例(中文注释)
"""
def dict_operations():
print('--- 字典操作示例 ---')
# 创建
d = {}
print('空字典:', d)
d = {'name': 'Alice', 'age': 25}
print('初始字典:', d)
# 更多创建方式
d_from_list = dict([('a', 1), ('b', 2)])
print('从列表创建:', d_from_list)
d_from_zip = dict(zip(['x', 'y', 'z'], [10, 20, 30]))
print('从zip创建:', d_from_zip)
d_fromkeys = dict.fromkeys(['key1', 'key2', 'key3'], 'default_value')
print('fromkeys创建:', d_fromkeys)
# C/U
d['city'] = 'Beijing'
print('d["city"] = "Beijing":', d)
d.setdefault('country', 'China')
print('setdefault("country", "China"):', d)
d['age'] = 26 # 更新
print('更新 age:', d)
# R
print('d["name"] =', d['name'])
print('d.get("age") =', d.get('age'))
print('d.get("salary", "N/A") =', d.get('salary', 'N/A'))
print('keys():', list(d.keys()))
print('values():', list(d.values()))
print('items():', list(d.items()))
# D
del d['city']
print('del d["city"]:', d)
popped = d.pop('age')
print('pop("age") 返回:', popped, ';字典:', d)
last = d.popitem()
print('popitem() 返回:', last, ';字典:', d)
d.clear()
print('clear():', d)
print()
def set_operations():
print('--- 集合操作示例 ---')
# 创建
s = set()
print('空集合:', s)
s = {1, 2, 3}
print('初始集合:', s)
fs = frozenset([4, 5, 6])
print('不可变集合:', fs)
# C
s.add(4)
print('add(4):', s)
s.update([5, 6])
print('update([5, 6]):', s)
# R
print('4 in s =', 4 in s)
print('len(s) =', len(s))
# D
s.remove(4)
print('remove(4):', s)
s.discard(10) # 不存在也不报错
print('discard(10):', s)
popped = s.pop()
print('pop() 返回:', popped, ';集合:', s)
# 数学运算
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print('a =', a, '; b =', b)
print('并集 a | b =', a | b)
print('交集 a & b =', a & b)
print('差集 a - b =', a - b)
print('对称差集 a ^ b =', a ^ b)
print('a 是 b 的子集? a <= b =', a <= b)
print('a 是 b 的超集? a >= b =', a >= b)
print()
def performance_comparison():
print('--- 性能对比示例 ---')
import time
# 创建大数据集
large_list = list(range(100000))
large_dict = {i: i for i in range(100000)}
# 测试查找性能
target = 99999
iterations = 1000
# 列表查找(线性)
start = time.perf_counter()
for _ in range(iterations):
found_in_list = target in large_list
list_time = time.perf_counter() - start
# 字典查找(哈希)
start = time.perf_counter()
for _ in range(iterations):
found_in_dict = target in large_dict
dict_time = time.perf_counter() - start
print('查找 {} 在 100000 个元素中(重复 {} 次):'.format(target, iterations))
print('列表查找:{},总耗时:{:.6f} 秒'.format(found_in_list, list_time))
print('字典查找:{},总耗时:{:.6f} 秒'.format(found_in_dict, dict_time))
print('字典查找快 {:.1f} 倍'.format(list_time / dict_time if dict_time > 0 else float('inf')))
print()
def main():
dict_operations()
set_operations()
performance_comparison()
if __name__ == '__main__':
main()
3.1. 字典(Dictionary)
映射(Mapping)类型
存储键值对(key-value pairs)
通过键访问对应的值,支持快速查找和修改。
核心特性:
键(Key)唯一且不可变
值(Value)可以是任意类型
字典通常被认为是无序的
3.1.1. 操作
创建字典:
{}:创建空字典。{'key1': value1, 'key2': value2, ...}:创建包含初始键值对的字典。dict(iterable):将可迭代对象转换为字典。
可以通过包含元组的列表或者zip()对象创建字典。dict.fromkeys(keys, value):使用指定的键列表创建字典,所有键对应相同的初始值。
CRUD:
- C/U:
dict[key] = value:添加或更新键值对。setdefault(key, default):如果键不存在,添加键并设置默认值。
- R:
dict[key]:通过键访问对应的值。
键不存在时抛出KeyError异常。get(key, default):通过键访问值,键不存在时返回默认值。
更安全keys():返回字典的所有键。values():返回字典的所有值。items():返回字典的所有键值对。
- D:
del dict[key]:删除指定键的键值对。pop(key, default):删除并返回指定键的值,键不存在时返回默认值。popitem():删除并返回一个任意键值对(Python 3.7+为最后一个)。clear():清空字典所有键值对。
3.2. 集合(Set)
无序、不重复的元素集合
核心特性:
- 元素必须是不可变的
- 自动去重:定义时重复元素会被自动移除。
3.2.1. 操作
创建集合:
{elem1, elem2, ...}:创建包含初始元素的集合。
特别注意:使用空花括号{}会创建一个空字典,而不是集合。set():创建空集合。set(iterable):将可迭代对象转换为集合。frozenset(iterable):创建不可变集合。
CRUD:
- C:
add(elem):向集合添加元素。update(iterable):将可迭代对象的元素添加到集合中。
- R:
- 通过
in运算符检查元素是否在集合中存在。 len():获取集合中元素的数量。
- 通过
- U:
集合本身不支持更新操作,但可以通过添加和删除元素来间接实现更新。 - D:
remove(elem):从集合中移除指定元素,元素不存在时抛出KeyError异常。discard(elem):从集合中移除指定元素,元素不存在时不抛出异常。pop():随机移除并返回一个元素,集合为空时抛出KeyError异常。
数学运算:
- 并集(Union):
A | B或A.union(B),返回包含A和B所有元素的新集合。 - 交集(Intersection):
A & B或A.intersection(B),返回同时存在于A和B的元素的新集合。 - 差集(Difference):
A - B或A.difference(B),返回存在于A但不在B中的元素的新集合。 - 对称差集(Symmetric Difference):
A ^ B或A.symmetric_difference(B),返回存在于A或B但不同时存在于两者的元素的新集合。 - 子集和超集:
A <= B检查A是否为B的子集,A >= B检查A是否为B的超集。
3.3. 性能对比
字典/集合:
基于哈希表实现,查找、插入和删除操作平均时间复杂度为O(1)。
不随着数据量增加而显著变慢。
占用空间更大。
列表/元组:
线性结构
索引查找快,但按值查找慢,平均时间复杂度为O(n)。
占用空间小
建议:
处理大规模数据的成员检测或查找时
最好将列表结构重构为字典结构
显著提升性能。