Files
2025PY/Python学习笔记.md
JYcdt f1909cd28f update README.md
更新数据容器类数据
2025-06-14 15:59:07 +08:00

3173 lines
71 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Python学习笔记
## Day 1: Python基础入门
### 1.1 开发环境配置
- 安装VSCode编辑器
- 安装Python插件
- 创建第一个.py文件
### 1.2 第一个Python程序
```python
print('hello world')
print(1+2+3)
```
### 1.3 print函数详解
- print函数用于输出内容到终端
- 默认情况下print函数输出的内容会自动换行
- 使用end参数可以控制输出格式
```python
# 默认换行输出
print(1)
print(2)
print(3)
# 使用end参数自定义分隔符
print(1, end='---')
print(2, end='---')
print(3, end='---')
# 使用逗号分隔输出
print('你好', end=',')
print('世界')
```
### 1.4 字面量和常量
- **字面量**:程序中直接使用的固定值
- 数字字面量:如 `3.14`
- 字符串字面量:如 `'hello'`
- **常量**
- 给特定值取一个名字
- 命名约定使用大写字母
- 值不应该被修改
```python
PI = 3.14
print(PI)
```
- **变量**
- 给特定值取一个名字
- 值可以随时修改
```python
name = 'zhangsan'
name = '张三'
print(name)
```
### 1.5 注释
- **注释的作用**:对代码进行解释说明,供程序员阅读
- **注释的类型**
1. 单行注释:以 `#` 开头
```python
# 这里是一个常量
COUNT = 100
```
2. 多行注释:使用三引号 `"""` 或 `'''`
```python
"""
a变量的值是1
b变量的值是2
c变量的值是3
"""
a = 1
b = 2
c = 3
```
### 1. if语句的梳理
```python
# if语句 单分支
num = -10
if num > 0:
print('num是正数')
# if else语句 双分支
age = int(input('请输入你的年龄'))
if age>=18:
print('成年人')
else:
print('没有成年')
# elif语句 多分支
num = int(input('请输入一个数字'))
if num>0:
print('正数')
elif num<0:
print('负数')
else:
print('等于0')
```
## Day 2: 字符串与输入输出
### 2.1 字符串操作
- 字符串拼接:`+` 号
- 字符串重复:`*` 号
- 成员运算:`in` / `not in`
- 索引取值:`str[i]`
- 负数索引:`str[-1]` 表示最后一个字符
示例代码:
```python
s1 = '我的名字是'
s2 = '佳佳'
print(s1 + s2)
name = '张三'
print('我的名字是' + name)
str1 = '我要成功'
print(str1 * 5)
str2 = 'my name is zhangsan'
print('y' in str2)
print('yy' in str2)
print('name' in str2)
str3 = 'zhangsan'
print('san' not in str3)
print('lisi' not in str3)
str4 = '你好世界'
print(str4[0], str4[1], str4[2], str4[3])
print(str4[0] + str4[2] + str4[-1])
```
### 2.2 输入与输出
- `input()` 用于获取用户输入,返回字符串类型
- `print()` 用于输出内容
示例代码:
```python
name = input('请输入你的名字')
print('你输入的内容是' + name)
n1 = input('请输入第一个数字')
n2 = input('请输入第二个数字')
print(n1 + n2) # 字符串拼接
# 转换为整数再相加
n1 = int(input('请输入第一个数字'))
n2 = int(input('请输入第二个数字'))
print(n1 + n2)
```
### 2.3 数据类型检测与转换
- `type()` 检测数据类型
- `int()`、`float()`、`str()` 类型转换
示例代码:
```python
n1 = input('请输入一个数字')
print(type(n1)) # str
print(type(int(n1))) # int
n1 = input('请输入第一个数字')
n2 = input('请输入第二个数字')
n1 = int(n1)
n2 = int(n2)
print(n1 + n2)
print(n1 - n2)
print(n1 * n2)
print(n1 / n2)
```
### 2.4 变量与数据类型基础
- Python变量无需声明类型类型由赋值自动推导
- 常见类型int、float、str、bool
### 2.5 列表的基本操作
- 创建、添加、访问、获取长度
示例代码:
```python
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
first_fruit = fruits[0]
num_fruits = len(fruits)
```
## Day 3: 运算符与变量
### 3.1 数据类型转换函数
- `int(x)`将x转为整数
- `float(x)`将x转为浮点数
- `str(x)`将x转为字符串
- 布尔值、浮点数、字符串之间的转换
示例代码:
```python
print(int('100')) # 100
print(int(True)) # 1
print(int(3.14)) # 3
print(float(100)) # 100.0
print(str(True)) # 'True'
```
### 3.2 算术运算符
- `+` 加法
- `-` 减法
- `*` 乘法
- `/` 除法
- `//` 取整除
- `%` 取余
- `**` 幂运算
示例代码:
```python
print(1 + 2) # 3
print(7 - 9) # -2
print(2 * 3) # 6
print(8 / 3) # 2.666...
print(9 // 2) # 4
print(9 % 2) # 1
print(2 ** 3) # 8
# 布尔值参与运算
print(True + True) # 2
print(True - True) # 0
print(True * True) # 1
print(True / True) # 1.0
```
### 3.3 赋值运算符
- `=` 赋值,将右边的值赋给左边变量
示例代码:
```python
a = 100
a = a + 2
print(a) # 102
num = 10
num = num + num + num + 100
print(num) # 130
```
### 3.4 复合赋值运算符
- `+=`、`-=`、`*=`、`/=`、`//=`、`%=`、`**=`
示例代码:
```python
a = 1
a += 1
print(a) # 2
a = 1
b = 2
c = 3
a += b
a -= c
b += c
c += b
print(a, b, c) # 0 5 8
```
### 3.5 内置的数字运算函数
- `abs(x)`:绝对值
- `divmod(x, y)`:返回(x//y, x%y)
- `pow(x, y, z=None)`:幂运算,可取模
- `round(x, n=0)`四舍五入保留n位小数
- `max(x1, x2, ...)`:最大值
- `min(x1, x2, ...)`:最小值
示例代码:
```python
print(abs(-100)) # 100
print(divmod(9, 2)) # (4, 1)
print(pow(2, 3)) # 8
print(round(3.6678, 3)) # 3.668
print(max(23, 45, 67, 89)) # 89
print(min(23, 45, 67, 89)) # 23
```
### 3.6 变量
- 变量就像盒子,可以存放内容
- 变量声明格式:变量名 = 值
- 变量的值可以改变
- 变量名要有语义
示例代码:
```python
name = 'zhangsan'
age = 18
sex = '男'
grade = 'IT231'
print(name, age, sex, grade)
```
## Day 4: 变量命名与字符串格式化
### 4.1 变量命名规则与标识符
- 变量名只能包含字母、数字和下划线,不能以数字开头
- 不能使用Python关键字和函数名
- 变量名应简短且有描述性
- 标识符区分大小写,不能是关键字或保留字
### 4.2 字符串的定义与嵌套
- 单引号、双引号、三引号均可定义字符串
- 三引号支持多行字符串
- 引号可嵌套使用
### 4.3 字符串拼接与格式化
- `+` 号拼接字符串
- `%` 占位符格式化字符串(%s, %d, %f
- `f"{}"` 格式化字符串(推荐)
示例代码:
```python
name = '张三'
age = 18
gender = '男'
print('我的名字是' + name + ',我今年' + str(age) + '岁,我是' + gender + '的')
print('我的名字是%s,我今年%s岁,我是%s的' % (name, age, gender))
print(f'我的名字是{name},我今年{age}岁,我是{gender}的')
```
### 4.4 字符串格式化表达式
```python
print("1 * 1的结果是:%d" % (1 * 1))
print(f"1 * 2的结果是:{1 * 2}")
print("字符串在Python中的类型名是:", type("字符串"))
```
### 4.5 变量交换与小数处理
- 不用第三变量交换两个数
- 保留小数位(不四舍五入)
示例代码:
```python
# 保留两位小数(不四舍五入)
origin = 123.456789
print(int(origin * 100) / 100) # 123.45
# 交换变量
a = 5
b = 8
a = a + b
b = a - b
a = a - b
print(a, b) # 8 5
```
### 4.6 综合练习
- 计算小时转天和小时
- 输入两个数字,输出和、差、积、商、余数
示例代码:
```python
# 小时转天和小时
hours = 89
day = int(hours / 24)
h = hours % 24
print('为抵抗洪水战士连续作战89小时编程计算共' + str(day) + '天零' + str(h) + '小时')
# 输入两个数字,输出运算结果
x = float(input("请输入第一个数字 x: "))
y = float(input("请输入第二个数字 y: "))
print(f"{x} + {y} = {x + y}")
print(f"{x} - {y} = {x - y}")
print(f"{x} * {y} = {x * y}")
print(f"{x} / {y} = {x / y}")
print(f"{x} % {y} = {x % y}")
```
## Day 5: 条件判断与分支结构
### 5.1 条件测试与比较运算符
- `==` 等于
- `!=` 不等于
- `>` 大于
- `<` 小于
- `>=` 大于等于
- `<=` 小于等于
- `and` 多条件同时满足
- `or` 多条件有一个满足
- `in` 检查成员
- `not in` 检查非成员
示例代码:
```python
n1 = 10
n2 = 10
n3 = 20
print(n1 == n2) # True
print(n1 != n3) # True
str1 = 'hello'
str2 = 'Hello'
print(str1 == str2.lower()) # True
print(5 == 5 and 10 != 5) # True
print(5 != 10 or 10 == 15) # True
print('e' in 'hello') # True
print('he' not in 'hello') # False
```
### 5.2 程序的三大结构
- 顺序结构
- 选择结构(分支)
- 循环结构
### 5.3 if语句
- 单分支
- 双分支
- 多分支elif
示例代码:
```python
# 单分支
n1 = -10
if n1 > 0:
print('这个是正数')
# 双分支
age = 10
if age >= 18:
print('成年了')
else:
print('没有成年')
# 多分支
num = int(input("请输入一个整数: "))
if num > 0:
print("这个数是正数")
elif num < 0:
print("这个数是负数")
else:
print("这个数是零")
```
### 5.4 综合练习与应用
- 判断闰年
- 补零输出
- 判断奇偶数
- 判断字符类型
- 判断水仙花数
- 密码判断
示例代码:
```python
# 判断闰年
year = int(input('请输入一个年份:'))
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
print(f"{year} 是闰年")
else:
print(f"{year} 不是闰年")
# 补零输出
num = int(input('请输入一个数字:'))
if num < 10:
print(f"0{num}")
else:
print(num)
# 判断奇偶数
num = int(input("请输入一个整数: "))
if num % 2 == 0:
print("这个数是偶数")
else:
print("这个数是奇数")
# 判断水仙花数
num = int(input('请输入一个三位的数字:'))
a = num % 10
b = num % 100 // 10
c = num // 100
if a**3 + b**3 + c**3 == num:
print(f'你输入的三位数{num}是水仙花数')
else:
print(f'你输入的三位数{num}不是水仙花数')
# 密码判断
correct_password = "python123"
password = input("请输入密码: ")
if password == correct_password:
print("密码正确,欢迎进入系统!")
else:
print("密码错误,请重试。")
```
## Day 6: 多分支与综合练习
### 6.1 多分支结构elif
- 结构:
```python
if 条件1:
# 条件1成立时执行
elif 条件2:
# 条件2成立时执行
elif 条件3:
# 条件3成立时执行
else:
# 所有条件都不成立时执行
```
- 应用:数字正负零判断、成绩评级等
示例代码:
```python
num = int(input('请输入一个数字'))
if num > 0:
print(f'你输入的数字{num}是一个大于0的数字')
elif num < 0:
print(f'你输入的数字{num}是一个小于0的数字')
else:
print(f'你输入的数字{num}是一个等于0的数字')
score = int(input("请输入分数:"))
if 90 <= score <= 100:
print("你的成绩等级是 A")
elif 80 <= score < 90:
print("你的成绩等级是 B")
elif 70 <= score < 80:
print("你的成绩等级是 C")
elif 60 <= score < 70:
print("你的成绩等级是 D")
elif 0 <= score < 60:
print("你的成绩等级是 F")
else:
print("分数输入错误,请输入 0-100 之间的整数")
```
### 6.2 综合练习
- 判断奇偶
- 判断正负零
- 绝对值计算
- 比较两个数大小
- 能否被3和5同时整除
- 判断闰年
- 简单计算器
- 判断三角形类型
- 字母大小写转换
- 生肖计算
- ATM取款机
- 简单彩票系统
示例代码(部分):
```python
# 判断奇偶
num = int(input("请输入一个整数:"))
if num % 2 == 0:
print(f"{num} 是偶数")
else:
print(f"{num} 是奇数")
# 绝对值
num = int(input("请输入一个整数:"))
if num < 0:
num = -num
print(f"绝对值是 {num}")
# 简单计算器
num1 = float(input("请输入第一个数:"))
operator = input("请输入运算符(+、-、*、/")
num2 = float(input("请输入第二个数:"))
if operator == "+":
print(f"结果是 {num1 + num2}")
elif operator == "-":
print(f"结果是 {num1 - num2}")
elif operator == "*":
print(f"结果是 {num1 * num2}")
elif operator == "/":
if num2 == 0:
print("除数不能为 0")
else:
print(f"结果是 {num1 / num2}")
else:
print("无效的运算符")
# 判断三角形类型
a, b, c = map(int, input("请输入三条边长(用空格分隔):").split())
if a + b > c and a + c > b and b + c > a:
if a == b == c:
print("等边三角形")
elif a == b or b == c or a == c:
print("等腰三角形")
elif a ** 2 + b ** 2 == c ** 2 or a ** 2 + c ** 2 == b ** 2 or b ** 2 + c ** 2 == a ** 2:
print("直角三角形")
else:
print("普通三角形")
else:
print("无法构成三角形")
# 生肖计算
zodiac = ["猴", "鸡", "狗", "猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊"]
year = int(input("请输入年份:"))
print(f"{year} 属 {zodiac[year % 12]}")
```
## Day 7: 条件语句进阶
### 7.1 if语句基础
```python
# if语句 单分支
num = -10
if num > 0:
print('num是正数')
# if else语句 双分支
age = int(input('请输入你的年龄'))
if age>=18:
print('成年人')
else:
print('没有成年')
# elif语句 多分支
num = int(input('请输入一个数字'))
if num>0:
print('正数')
elif num<0:
print('负数')
else:
print('等于0')
```
### 7.2 if语句嵌套
- 在if语句内部可以嵌套其他if语句
- 外层条件满足时才会执行内层条件判断
- 语法结构:
```python
if 外层条件:
# 外层条件为真时执行的代码
if 内层条件:
# 内层条件为真时执行的代码
else:
# 内层条件为假时执行的代码
else:
# 外层条件为假时执行的代码
```
示例代码:
```python
# 判断是否有火车票和刀具长度
ticket = True
knife = 34
if ticket==True:
print('恭喜你 有票')
if knife<10:
print('可以携带')
else:
print('不可以携带')
else:
print('很遗憾 没有票')
# 猜拳游戏
import random
my_num = int(input('请输入数字0-2:')) # 0:石头 1:剪刀 2:布
if my_num <= 2:
computer_num = random.randint(0,2)
if (my_num == 0 and computer_num==1) or (my_num == 1 and computer_num == 2) or (my_num == 2 and computer_num == 0):
print(f'我们赢了,计算机是{computer_num},恭喜!')
else:
print(f'我们输了,计算机是{computer_num},计算机赢了')
else:
print('你输入的数字不合法')
```
### 7.3 综合练习
1. 比较两个数的大小
```python
n1 = int(input('请输入第一个整数:'))
n2 = int(input('请输入第二个整数:'))
if n1 > n2:
print(f'最大的数字是:{n1}')
elif n1 < n2:
print(f'最大的数字是:{n2}')
else:
print(f'n1:{n1}和n2:{n2}是相等的')
```
2. 判断三角形类型
```python
n1 = int(input('请输入第一个边的长度:'))
n2 = int(input('请输入第二个边的长度:'))
n3 = int(input('请输入第三个边的长度:'))
if n1 == n2 == n3:
print(f'你输入的n1={n1},n2={n2},n3={n3}相同是等边三角形')
elif n1 == n2 or n2 == n3 or n1 == n3:
print(f'你输入的n1={n1},n2={n2},n3={n3}任意两边相同是等腰三角形')
else:
print('你输入的三个数字不相等,是一个普通三角形')
```
3. 体重标准判断
```python
height = int(input('请输入你的身高cm'))
weight = int(input('请输入你的体重斤:'))
max_weight = (height-108)* 2 + 10 # 最大体重的分界点
min_weight = (height-108)* 2 - 10 # 最小体重的分界点
if weight > max_weight:
print('你太胖了,需要减减肥!')
elif weight < min_weight:
print('你太瘦了,需要多多加强营养!')
else:
print('你是标准身材,请继续保持!')
```
## Day 8: 循环结构基础
### 8.1 高级练习
1. 复杂身份验证系统
```python
username = input("请输入用户名: ")
password = input("请输入密码: ")
if username == "admin":
if password == "admin123":
print("欢迎管理员登录!")
else:
print("用户名或密码错误")
elif username == "user":
if password == "user456":
print("欢迎用户登录!")
else:
print("用户名或密码错误")
else:
print("用户不存在")
```
2. ATM取款机加强版
```python
balance = 10000
daily_limit = 10000 # 每日可取款额度
amount = int(input("请输入取款金额100 的倍数): "))
if amount % 100 != 0:
print("错误:取款金额必须是 100 的倍数")
elif amount > balance:
print("错误:余额不足")
elif amount > 3000:
print("错误:单次取款金额不得超过 3000 元")
elif amount > daily_limit:
print("错误:超过每日取款限额")
else:
balance -= amount
daily_limit -= amount
print(f"取款成功,余额为 {balance} 元,今日还可取 {daily_limit} 元")
```
3. 复杂成绩评级
```python
score = int(input("请输入成绩 (0-100): "))
if 95 <= score <= 100:
print("评级: A+")
if score == 100:
print("满分!你太棒了!")
elif 90 <= score < 95:
print("评级: A")
elif 85 <= score < 90:
print("评级: B+")
elif 80 <= score < 85:
print("评级: B")
elif 70 <= score < 80:
print("评级: C")
elif 60 <= score < 70:
print("评级: D")
elif 0 <= score < 60:
print("评级: F")
else:
print("输入错误,请输入 0-100 之间的成绩")
```
### 8.2 循环的意义
- 循环是程序中广泛存在的基础功能
- 用于重复执行某些操作
- Python中的循环语句
1. while循环
2. for...in循环
- 循环的组成:
1. 定义循环的关键字while/for/in
2. 限制条件(终止条件)
3. 循环体(满足条件执行的代码)
- 死循环:无法靠自身条件终止的循环
### 8.3 while循环
- 语法结构:
```python
while 判断条件:
满足条件执行语句
...
```
- 注意事项:
1. 初始值
2. while + 限制条件
3. 满足条件执行的循环体
4. 初始值的迭代(累加/累减)
示例代码:
```python
# 打印100-200之间能被3和7整除的数
num = 100 # 初始值
while num <= 200: # 条件1100-200
# 条件2能被3和7整除
if(num % 3 == 0 and num % 7 == 0):
print(num) # 打印结果
num += 1 # 累加 初始值的迭代
```
## Day 9: 循环控制语句
### 9.1 正向和反向循环
```python
# 正向循环输出数字1-10
num = 1
while num <= 10:
print(num)
num += 1
# 反向循环输出数字10-1
num = 10
while num >= 1:
print(num)
num -= 1
```
### 9.2 break和continue关键字
- break直接结束整个循环
- continue中断本次循环继续下一次循环
示例代码:
```python
# break示例
num = 1
while num <= 10:
if num == 5:
break # 当num等于5时结束循环
print(f'这是第{num}次循环')
num += 1
# continue示例
num = 0
while num < 10:
num += 1
if num == 5:
continue # 当num等于5时跳过本次循环
print(f'这是第{num}次循环')
```
### 9.3 循环练习
1. 打印1-100之间的偶数
```python
num = 1
while num <= 100:
if num % 2 == 0:
print(num)
num += 1
```
2. 计算1-100的和
```python
sum = 0
num = 1
while num <= 100:
sum += num
num += 1
print(f'1到100的和是{sum}')
```
3. 打印九九乘法表
```python
i = 1
while i <= 9:
j = 1
while j <= i:
print(f'{j}×{i}={i*j}', end='\t')
j += 1
print() # 换行
i += 1
```
4. 猜数字游戏
```python
import random
target = random.randint(1, 100)
count = 0
while True:
guess = int(input('请猜一个1-100之间的数字'))
count += 1
if guess > target:
print('太大了')
elif guess < target:
print('太小了')
else:
print(f'恭喜你猜对了!答案就是{target}')
print(f'你总共猜了{count}次')
break
```
## Day 10: for循环与三目运算符
### 10.1 三目运算符
- 语法:`结果1 if 条件 else 结果2`
- 作用:根据条件判断,选择不同的结果
示例代码:
```python
a = 100
b = 20
max = a if a > b else b
print(max)
# 等价于:
if a > b:
max = a
else:
max = b
print(max)
```
### 10.2 for循环
- for循环用于对序列类型如字符串、列表、元组等进行逐个处理
- 语法结构:
```python
for 临时变量 in 待处理的数据集:
循环体
```
- 临时变量:每次循环时取到的数据项
- 循环体:对每个数据项要执行的操作
示例代码:
```python
str = 'hello'
for s in str:
print(s)
```
### 10.3 range函数
- 用于生成一系列数字常与for循环配合使用
- 用法:
- `range(num)`从0到num-1
- `range(start, end)`从start到end-1
- `range(start, end, step)`从start到end-1步长为step
示例代码:
```python
for n in range(10):
print(n)
for n in range(1, 10):
print(n)
for n in range(1, 10, 2):
print(n)
```
## Day 11: 循环案例精讲
### 11.1 求100-999之间的水仙花数
- 水仙花数一个n位数其每个位上的数字的n次幂之和等于它本身。
- 三位数水仙花数示例1531^3 + 5^3 + 3^3 = 153
示例代码:
```python
for num in range(100, 1000):
a = num % 10 # 个位
b = num % 100 // 10 # 十位
c = num // 100 # 百位
if a**3 + b**3 + c**3 == num:
print(num, end=',')
```
### 11.2 打印100以内不带7且不是7的倍数的数
- 条件不是7的倍数个位和十位都不能是7
示例代码:
```python
for num in range(1, 101):
if (num % 7 != 0) and (num % 10 != 7) and (num // 10 != 7):
print(num, end=',')
```
### 11.3 判断素数
- 素数只能被1和自身整除的数最小的素数是2
示例代码:
```python
num = int(input('请输入一个数字:'))
flag = True
if num < 2:
flag = False
else:
for i in range(2, num):
if num % i == 0:
flag = False
break
if flag:
print(f'{num}是素数')
else:
print(f'{num}不是素数')
```
## Day 12: 数据容器入门与列表
### 12.1 数据容器入门
- 数据容器是一种可以容纳多个数据的数据类型,每个数据被称为元素。
- 数据容器的特点:
1. 可以容纳多份数据。
2. 是否支持重复数据。
3. 是否可以修改。
4. 是否有序。
- 数据容器的类型:
- 列表(list)
- 元组(tuple)
- 字符串(str)
- 集合(set)
- 字典(dict)
### 12.2 列表的创建与索引
- 列表由一系列按照特定顺序排列的元素组成。
- 定义方式:使用方括号`[]`,用逗号分隔元素。
- 示例代码:
```python
list_names = ['李一', '张三', '李四']
list_nums = [100, 200, 300, 400]
print(list_names, list_nums)
```
- 输出列表的值和类型:
```python
print(list_names)
print(type(list_names)) # <class 'list'>
```
- 下标索引列表的每个元素都有一个编号从左到右默认从0开始。
- 示例代码:
```python
list_names = ['李一', '张三', '李四', '老王', 'wangwu']
print(list_names[0]) # 李一
print(list_names[1]) # 张三
print(list_names[2]) # 李四
print(list_names[3]) # 老王
print(list_names[4]) # wangwu
```
- 修改元素的值:
```python
list_names[1] = '尼古拉斯'
print(list_names) # ['李一', '尼古拉斯', '李四', '老王', 'wangwu']
```
- 反向索引:从后到前,从-1开始。
- 示例代码:
```python
print(list_names[-1]) # wangwu
print(list_names[-2]) # 老王
print(list_names[-3]) # 李四
print(list_names[-4]) # 张三
print(list_names[-5]) # 李一
```
- 列表可以存储多个数据,并且可以存储不同的数据类型,同时支持嵌套。
- 示例代码:
```python
list_nums = [[4, 5, 6], [6, 7, 8], [10, 11]]
print(list_nums[0]) # [4, 5, 6]
print(list_nums[0][0]) # 4
```
- 多维列表示例:
```python
list = [1, [2, 3, [4, [5, 6, [7, 8, [9, 10]]]]]]
print(list[1][2][1][2][2][0]) # 9
```
## Day 13: 列表的操作与常用方法
### 13.1 列表的操作
- 修改列表中的元素值:
```python
list = [100, 200, 300, 400, 500]
list[2] = 3
print(list) # [100, 200, 3, 400, 500]
```
- 修改区间值:
```python
list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list[1:5] = [100, 200, 300, 400] # 替换索引1到4的元素
print(list) # [0, 100, 200, 300, 400, 5, 6, 7, 8, 9]
```
- 添加步长:
```python
list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
list[1:9:2] = ['奇数', '奇数', '奇数', '奇数'] # 步长为2从索引1开始替换
print(list) # [0, '奇数', 2, '奇数', 4, '奇数', 6, '奇数', 8, 9]
```
- 重复列表:
```python
list = [1, 2, 3]
print(list * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
```
- 列表拼接:
```python
list = [12, 13, 14]
print(list + [4, 5, 6]) # [12, 13, 14, 4, 5, 6]
print(list + [4, 5, 6] + [20, 30, 40, 50]) # [12, 13, 14, 4, 5, 6, 20, 30, 40, 50]
```
### 13.2 列表的常用方法
- 在Python中一切皆对象列表也是一个对象由属性和方法组成。
- 常用方法:
1. `list.index(元素)`:查找指定元素在列表中的索引,如果找不到则报错。
2. `list.append(x)`将x作为一个元素添加到列表list中x可以是列表或元素
示例代码:
```python
list = ['zhangsan', 'lisi', 'wangwu']
print(list.index('lisi')) # 1
list = ['a', 'b']
list.append('c')
list.append('d')
list.append(['e', 'f', 'g'])
print(list) # ['a', 'b', 'c', 'd', ['e', 'f', 'g']]
```
- 案例创建一个列表里面是0开始的偶数一直到100。
```python
list = [] # 创建一个空列表
for num in range(0, 101): # 循环1-100
if num % 2 == 0: # 选择1-100的偶数
list.append(num) # 将偶数追加到列表中
print(list) # [0, 2, 4, ..., 100]
```
## Day 14: 列表的方法总结与应用
### 14.1 列表的方法总结
- `list.extend()`:将列表中的元素增加到列表中去。
- `list.pop(x)`如果括号里没有参数默认删除最后一项如果写了参数将列表中的第x个元素取出并删除。
- `list.remove(x)`将列表中出现的第一个元素x删除。
- `list.clear()`:删除所有的元素。
- `list.insert(i, x)`在列表的第i个位置插入字符x。
- `list.reverse()`将列表list里面的元素反转原地保存。
- `list.sort()`将列表list里面的元素排序。
示例代码:
```python
list = ['a', 'b']
list.extend('c')
list.extend(['d', 'e'])
print(list) # ['a', 'b', 'c', 'd', 'e']
list = ['a', 'b', 'c', 'd']
print(list.pop()) # 'd'
print(list) # ['a', 'b', 'c']
list = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
list.remove('c') # 删除第一个c字符
print(list) # ['a', 'b', 'd', 'e', 'f', 'g']
list = ['a', 'b', 'c', 'd', 'e']
list.clear()
print(list) # []
list = ['a', 'b', 'c', 'd']
list.insert(1, 'x') # 在下标为1的位置插入字符x
print(list) # ['a', 'x', 'b', 'c', 'd']
list = ['a', 'b', 'c']
list.insert(1, ['x', 'y', 'z']) # 在下标为1的位置插入多个字符
print(list) # ['a', ['x', 'y', 'z'], 'b', 'c']
list = ['a', 'b', 'c', 'd']
list.reverse()
print(list) # ['d', 'c', 'b', 'a']
list = [12, 3, 1, 78, 88, 90, 34, 56]
list.sort(reverse=False) # 默认升序
print(list) # [1, 3, 12, 34, 56, 78, 88, 90]
list = [1, 2, 36, 7, 89, 100, 34, 78]
list.sort(reverse=True) # 降序排序
print(list) # [100, 89, 78, 36, 34, 7, 2, 1]
```
## Day 15: 列表遍历与元组
### 15.1 列表的遍历
列表遍历是指按照需求依次取出列表中的元素进行操作。Python提供了两种遍历方式
1. while循环遍历
```python
list = ['apple', 'banana', 'orange', 'grape']
index = 0
while index < len(list):
print(list[index])
index += 1
```
2. for循环遍历
```python
list = ['apple', 'banana', 'orange', 'grape']
for v in list:
print(v)
```
while循环和for循环的对比
1. 循环条件控制:
- while循环可以自定义循环条件并自行控制
- for循环不可以自定义循环条件只能一个个从容器内取出数据
2. 无限循环:
- while循环可以通过条件控制做到无限循环
- for循环理论上不可以因为被遍历的容器容量不是无限的
3. 使用场景:
- while循环适用于任何想要循环的场景
- for循环适用于遍历数据容器的场景或简单的固定次数循环场景
### 15.2 列表遍历的应用
示例创建一个列表包含1-100的偶数每5个数求平均数并将平均值放入新列表
```python
# 第一步生成1-100的偶数列表
list = []
for i in range(1, 101):
if i % 2 == 0:
list.append(i)
print(list) # [2, 4, 6, ..., 100]
# 第二步每5个数求平均数
result = 0
new_list = []
for index in range(len(list)):
result += list[index]
if (index + 1) % 5 == 0:
new_list.append(result / 5)
result = 0
print(new_list) # [6.0, 16.0, 26.0, 36.0, 46.0, 56.0, 66.0, 76.0, 86.0, 96.0]
```
### 15.3 元组
元组tuple是一种不可变的数据容器可以封装多个不同类型的元素。
1. 定义元组:
```python
t1 = ('zhangsan', 'lisi', 'wangwu')
t2 = ('apple',) # 如果只有一个值,也要添加逗号,否则不是元组
print(type(t1)) # <class 'tuple'>
```
2. 元组的读写:
```python
# 读取元组的值
print(t1[0]) # 'zhangsan'
print(t1[1]) # 'lisi'
print(t1[2]) # 'wangwu'
# 修改元组的值(会报错)
# t1[0] = '张三' # TypeError: 'tuple' object does not support item assignment
```
3. 元组的嵌套:
```python
t1 = (('zhangsan', 'lisi', 'wangwu'), ('apple', 'orange'), ('jack', 'tom'))
print(t1[0]) # ('zhangsan', 'lisi', 'wangwu')
print(t1[0][1]) # 'lisi'
```
元组的特点:
- 有序:可以通过索引访问元素
- 不可变:一旦定义后不能修改
- 可以包含重复值
- 可以包含不同类型的元素
- 支持嵌套使用
## Day 16: 元组的进阶操作
### 16.1 元组的操作符
1. 拼接和重复:
```python
t1 = (1, 2, 3)
t2 = (4, 5, 6)
print(t1 + t2) # (1, 2, 3, 4, 5, 6) 拼接
print(t1 + (7, 8, 9)) # (1, 2, 3, 7, 8, 9) 拼接
print(t1 * 4) # (1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3) 重复
```
2. in操作符
```python
t1 = ('apple', 'orange', 'mango')
print('orange' in t1) # True
print('pear' in t1) # False
```
### 16.2 元组和列表的混合使用
元组中可以包含列表,且列表中的元素可以修改:
```python
t1 = ('zhangsan', ['a', 'b', 'c'])
print(t1[1]) # ['a', 'b', 'c']
print(t1[1][1]) # 'b'
t1[1][1] = 'B' # 修改列表中的元素
print(t1) # ('zhangsan', ['a', 'B', 'c'])
```
### 16.3 元组的遍历
```python
nums = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
for v in nums:
print(v * 100, end=',') # 将值扩大100倍
```
### 16.4 元组和列表的转换
1. list()函数:将可遍历对象转换为列表
```python
print(list('hello')) # ['h', 'e', 'l', 'l', 'o'] 字符串转列表
print(list((1, 2, 3, 4, 5))) # [1, 2, 3, 4, 5] 元组转列表
```
2. tuple()函数:将可遍历对象转换为元组
```python
print(tuple('hello')) # ('h', 'e', 'l', 'l', 'o') 字符串转元组
print(tuple([1, 2, 3, 4, 5])) # (1, 2, 3, 4, 5) 列表转元组
```
### 16.5 元组的方法和函数
1. 元组的方法:
- index():查找元素,返回下标(不存在则报错)
```python
t1 = ('banana', 'apple', 'mango', 'pear', 'orange')
print(t1.index('orange')) # 4
```
- count():统计元素出现次数
```python
t1 = ('apple', 'apple', 'apple', 'orange', 'pear')
print(t1.count('apple')) # 3
print(t1.count('hehe')) # 0
```
2. 元组的函数:
- len():统计元素个数
```python
t1 = ('apple', 'apple', 'apple', 'orange', 'pear', 'orange')
print(len(t1)) # 6
```
- sorted():排序(返回列表)
```python
t2 = (12, 4, 67, 8, 10, 1)
print(sorted(t2)) # [1, 4, 8, 10, 12, 67] 升序
print(sorted(t2, reverse=True)) # [67, 12, 10, 8, 4, 1] 降序
```
## Day 17: 集合
### 17.1 集合的基本概念
集合set是一种无序的数据容器具有以下特点
- 通过{}存储多个元素
- 无序的,随机顺序输出
- 不可以通过索引下标读写元素
- 不可以设置重复的值(自动去重)
1. 定义集合:
```python
s1 = {'zhangsan', 'lisi', 'zhangsan', 'lisi'} # 自动去重
print(s1) # {'zhangsan', 'lisi'}
```
2. 获取集合元素:
```python
s1 = {'shangsan', 'lisi', 'wangwu'}
for item in s1:
print(item)
```
3. 判断元素是否存在:
```python
s1 = {'zhangsan', 'lisi', 'wangwu', 'haha'}
print('zhangsan' in s1) # True
print('张三' in s1) # False
```
### 17.2 集合的方法和函数
1. 集合的方法:
- add():添加元素
```python
s1 = {'a', 'b', 'c'}
s1.add('d') # 添加单个元素
s1.add(('e', 'f')) # 添加元组
print(s1) # {('e', 'f'), 'b', 'c', 'a', 'd'}
```
- remove():移除指定元素
```python
s1 = {'apple', 'orange', 'banana'}
s1.remove('orange')
print(s1) # {'apple', 'banana'}
```
- pop():随机取出一个元素
```python
s1 = {'apple', 'orange', 'banana'}
print(s1.pop()) # 返回随机元素并从集合中删除
```
- clear():清空集合
```python
s1 = {'apple', 'orange', 'banana'}
s1.clear()
print(s1) # set()
```
2. 集合的运算:
- 并集union 或 |):获取所有元素
```python
s1 = {1, 2, 3}
s2 = {3, 4, 5}
print(s1.union(s2)) # {1, 2, 3, 4, 5}
print(s1 | s2) # {1, 2, 3, 4, 5}
```
- 交集intersection 或 &):获取共有元素
```python
s1 = {1, 2, 3, 4}
s2 = {1, 2, 3, 4, 5, 6}
print(s1.intersection(s2)) # {1, 2, 3, 4}
print(s1 & s2) # {1, 2, 3, 4}
```
- 差集difference 或 -):获取独有元素
```python
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7, 8, 9}
print(s1 - s2) # {1, 2}
print(s1.difference(s2)) # {1, 2}
```
- 非对称差集(^):获取非公共元素
```python
s1 = {1, 2, 3, 4, 5}
s2 = {3, 4, 5, 6, 7, 8, 9}
print(s1 ^ s2) # {1, 2, 6, 7, 8, 9}
```
### 17.3 集合的转换
```python
list_nums = [12, 34, 56, 78, 12, 34, 56, 78]
print(set(list_nums)) # {56, 34, 12, 78} 列表转集合(去重)
print(list(set(list_nums))) # [56, 34, 12, 78] 集合转列表
```
## Day 18: 数据容器梳理与字典
### 18.1 数据容器梳理
Python中的5种数据容器
1. 列表list
- 存储多个元素
- 有序
- 可以重复
- 可以通过索引下标进行读写
2. 元组tuple
- 存储多个元素
- 有序
- 可以重复
- 可以通过索引下标进行获取,不能修改
3. 集合set
- 存储多个元素
- 无序
- 不能重复
- 没有索引下标
- 可修改
4. 字典dict键值对形式存储数据
5. 字符串str字符序列
创建符号:
- 列表:[1, 2, 3, 4, 5]
- 元组:(1, 2, 3, 4, 5)
- 集合:{1, 2, 3, 4, 5}
- 字典:{'key': 'value'}
通用函数:
- len():统计元素个数
- sorted():对元素进行排序
### 18.2 字典的基本概念
字典是一种键值对形式的数据容器,具有以下特点:
- 使用{}存储数据
- 每条数据包含键key和值value
- 键值对之间用逗号分隔
- 键必须是唯一的,值可以重复
1. 字典的创建:
```python
student = {
'name': 'lisi',
'gender': '男',
'age': 20
}
print(type(student)) # <class 'dict'>
```
2. 字典的读写:
```python
# 读取值
print(student['name']) # 'lisi'
# 修改值
student['name'] = 'zhangsan'
print(student) # {'name': 'zhangsan', 'gender': '男', 'age': 20}
```
3. 字典的嵌套:
```python
my_dict = {
'k1': {'语文': 77, '数学': 66, '英语': 88},
'k2': {'语文': 71, '数学': 61, '英语': 81}
}
print(my_dict['k1']) # {'语文': 77, '数学': 66, '英语': 88}
print(my_dict['k1']['数学']) # 66
```
### 18.3 字典的方法
1. pop(key):删除指定键值对并返回值
```python
result = {'语文': 77, '数学': 66, '英语': 33}
print(result.pop('数学')) # 66
print(result) # {'语文': 77, '英语': 33}
```
2. popitem():删除并返回最后一对键值对
```python
result = {'语文': 77, '数学': 66, '英语': 33}
print(result.popitem()) # ('英语', 33)
print(result) # {'语文': 77, '数学': 66}
```
3. clear():清空字典
```python
result = {'语文': 77, '数学': 66, '英语': 33}
result.clear()
print(result) # {}
```
4. keys():获取所有键
```python
person = {
'name': 'zhangsan',
'sex': '男',
'age': 19,
'class': 'IT231'
}
print(person.keys()) # dict_keys(['name', 'sex', 'age', 'class'])
# 遍历键
for key in person.keys():
print(key)
```
5. values():获取所有值
```python
print(person.values()) # dict_values(['zhangsan', '男', 19, 'IT231'])
```
## Day 19: 数据容器梳理与算法题
### 19.1 数据容器梳理
数据容器是一种可以容纳多个数据的数据类型,每个数据被称为元素,可以是任意数据类型。
1. 列表list
- 使用中括号[]定义
- 特点:
- 可以重复
- 有序(有索引)
- 可以修改
- 操作:定义、遍历、方法和函数
2. 元组tuple
- 使用小括号()定义
- 特点:
- 可以重复
- 有序(有索引)
- 不可修改
- 操作:定义、遍历、方法和函数
3. 集合set
- 使用大括号{}定义
- 特点:
- 不可重复
- 无序
- 不可修改
- 操作:定义、遍历、方法和函数
4. 字典dict
- 使用大括号{}定义,存储键值对
- 特点:
- key不可重复重复会覆盖
- 无序(无索引)
- 可以修改值
- key和value可以是任意类型
- 操作:定义、遍历、方法和函数
5. 字符串str
- 使用引号定义
- 操作:遍历、方法和函数
### 19.2 数据容器的算法题
1. 列表反转:
```python
lst = [1, 2, 3, 4, 5]
reversed_lst = lst[::-1]
print(f"反转后的列表是 {reversed_lst}")
```
2. 查找列表中的最大值和最小值:
```python
lst = [3, 1, 7, 5, 2]
max_value = max(lst)
min_value = min(lst)
print(f"最大值是 {max_value}")
print(f"最小值是 {min_value}")
```
3. 字典的键值交换:
```python
d = {'a': 1, 'b': 2, 'c': 3}
reversed_dict = {v: k for k, v in d.items()}
print(f"反转后的字典是 {reversed_dict}")
```
4. 集合的运算:
```python
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union = set1 | set2
intersection = set1 & set2
difference = set1 - set2
print(f"并集是 {union}")
print(f"交集是 {intersection}")
print(f"差集是 {difference}")
```
5. 元组拆包:
```python
t = (1, 2, 3, 4)
a, b, c, d = t
print(f"拆包后的元素是 {a} {b} {c} {d}")
```
6. 列表去重:
```python
lst = [1, 2, 2, 3, 3, 4]
unique_lst = list(set(lst))
print(f"去重后的列表是 {unique_lst}")
```
7. 查找出现次数最多的元素:
```python
from collections import Counter
lst = [1, 2, 3, 1, 1, 2, 4]
counter = Counter(lst)
most_common_element = counter.most_common(1)[0][0]
print(f"出现次数最多的元素是 {most_common_element}")
```
8. 计算字典值的总和:
```python
d = {'Alice': 20, 'Bob': 25, 'Charlie': 30}
total = sum(d.values())
print(f"字典中所有值的总和是 {total}")
```
9. 字典合并:
```python
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged_dict = {**dict1, **dict2}
print(f"合并后的字典是 {merged_dict}")
```
10. 从列表中删除指定元素:
```python
lst = [1, 2, 3, 1, 4, 1, 5]
remove_element = 1
new_lst = [x for x in lst if x != remove_element]
print(f"删除后的列表是 {new_lst}")
```
11. 列表中的嵌套字典:
```python
lst = [{'name': 'Alice', 'age': 20}, {'name': 'Bob', 'age': 25}]
key = 'name'
values = [d[key] for d in lst if key in d]
print(f"所有的 '{key}' 值是 {values}")
```
12. 找出列表中的最大和最小元素的差值:
```python
lst = [10, 2, 8, 6, 4]
max_val = max(lst)
min_val = min(lst)
diff = max_val - min_val
print(f"最大值和最小值之间的差是 {diff}")
```
## Day 20: 字符串的操作与方法
### 20.1 数据容器的区别
- 列表list有序、可重复、可修改
- 元组tuple有序、可重复、不可修改
- 集合set无序、不可重复、不可修改
- 字典dict无序、key重复会覆盖通过key访问
- 字符串str字符序列可遍历、不可修改
常用转换函数:
- list()、tuple()、set()、dict()、str()
### 20.2 字符串的基本操作
- 字符串是字符的容器,可以通过索引下标访问每个字符:
```python
str = 'hello'
print(str[0]) # h
print(str[-1]) # o
```
- 字符串不可修改(不可变类型)。
### 20.3 字符串的遍历
- while循环
```python
str = 'abcdefgh'
i = 0
while i < len(str):
print(str[i])
i += 1
```
- for循环
```python
str = 'ABCDEFGH'
for v in str:
print(v)
```
- 也可用for+range遍历索引。
### 20.4 字符串的常用方法
- lower() / upper():转小写/大写
- islower() / isnumeric():判断是否全小写/是否全为数字
- startswith()/endswith():判断是否以指定内容开头/结尾,可指定区间
- split():分割字符串为列表
- count():统计子串出现次数
- replace(old, new, count):替换子串
- center(width, fillchar):居中显示并填充
- strip(chars):去除两侧指定字符
- zfill(width)左侧补0到指定宽度
- join(iterator):用指定分隔符拼接序列
- format():格式化字符串
#### 示例代码:
```python
s = 'ABCdef'
print(s.lower()) # abcdef
print(s.upper()) # ABCDEF
print('hello'.startswith('h')) # True
print('hello'.endswith('o')) # True
print('a b c'.split()) # ['a', 'b', 'c']
print('hello,hello'.count('hello')) # 2
print('hello world'.replace('hello', 'hi')) # hi world
print('hello'.center(10, '*')) # **hello***
print(' abcd '.strip()) # abcd
print('zhangsan'.zfill(10)) # 000zhangsan
print('-'.join(['a', 'b', 'c'])) # a-b-c
print('我的名字是{0},我今年{1}岁'.format('zhangsan', 18))
```
## Day 21: 切片与字符串练习
### 21.1 切片的概念与语法
- 切片是从一个序列中截取出一个子序列的操作。
- 适用于列表、元组、字符串等序列类型。
- 语法:`序列[起始下标:结束下标:步长]`
- 起始下标:截取的起始位置,留空表示从头开始。
- 结束下标:截取的结束位置,不包含该位置,留空表示到结尾。
- 步长每次取值的间隔默认为1负数表示反向取值。
#### 示例:
```python
lst = [0,1,2,3,4,5,6,7,8,9]
print(lst[2:6]) # [2, 3, 4, 5]
print(lst[::2]) # [0, 2, 4, 6, 8]
print(lst[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
print(lst[-2:-5:-1]) # [8, 7, 6]
s = '0123456789'
print(s[2:5]) # 234
print(s[::-1]) # 9876543210
t = (0,1,2,3,4,5,6,7,8,9)
print(t[::-2]) # (9, 7, 5, 3, 1)
```
### 21.2 切片与字符串常见练习
1. 反转列表/字符串:
```python
lst = [1, 2, 3, 4, 5]
print(lst[::-1]) # [5, 4, 3, 2, 1]
s = "hello"
print(s[::-1]) # "olleh"
```
2. 获取子列表:
```python
lst = [10, 20, 30, 40, 50, 60]
print(lst[2:5]) # [30, 40, 50]
```
3. 隔一个取一个:
```python
s = "abcdefghij"
print(s[::2]) # "acegik"
```
4. 删除前三个元素:
```python
lst = [1,2,3,4,5,6,7,8,9]
lst = lst[3:]
print(lst) # [4, 5, 6, 7, 8, 9]
```
5. 替换中间元素:
```python
lst = [1,2,3,4,5]
lst[len(lst)//2:len(lst)//2+1] = [10]
print(lst) # [1, 2, 10, 4, 5]
```
6. 检查回文:
```python
def is_palindrome(s):
return s == s[::-1]
print(is_palindrome("radar")) # True
```
7. 合并切片:
```python
a = [1,2,3]
b = [4,5,6]
print(a[:2] + b[-2:]) # [1, 2, 5, 6]
```
8. 矩阵转置:
```python
matrix = [[1,2],[3,4],[5,6]]
transposed = [list(row) for row in zip(*matrix)]
print(transposed) # [[1, 3, 5], [2, 4, 6]]
```
9. 字符串重组:
```python
s = "HelloWorld"
idx = s.index("World")
print(s[idx:] + s[:idx]) # "WorldHello"
```
10. 列表深拷贝与浅拷贝:
```python
import copy
original = [1, 2, [3, 4]]
shallow_copy = original[:]
deep_copy = copy.deepcopy(original)
shallow_copy[2][0] = 99
print(original) # [1, 2, [99, 4]]
deep_copy[2][0] = 100
print(original) # [1, 2, [99, 4]]
```
### 21.3 字符串常见练习
1. 判断是否是回文:
```python
s = "racecar"
print(s == s[::-1]) # True
```
2. 统计某个字符出现次数:
```python
s = "hello"
print(s.count("l")) # 2
```
3. 删除字符串中的元音:
```python
s = "beautiful"
vowels = "aeiouAEIOU"
new_s = ''.join(c for c in s if c not in vowels)
print(new_s) # "btfl"
```
4. 计算字符串中的单词数量:
```python
s = "I love Python"
print(len(s.split())) # 3
```
5. 检查字符串是否只包含字母:
```python
s = "Python123"
print(s.isalpha()) # False
```
6. 字符串大小写转换:
```python
s = "Hello World"
print(s.swapcase()) # "hELLO wORLD"
```
7. 删除字符串中的重复字符(保留首次顺序):
```python
s = "banana"
seen = set()
new_s = ''.join(seen.add(c) or c for c in s if c not in seen)
print(new_s) # "ban"
```
8. 获取第一个不重复的字符:
```python
s = "swiss"
for c in s:
if s.count(c) == 1:
print(c) # "w"
break
```
9. 反转字符串中的单词:
```python
s = "I love Python"
print(' '.join(s.split()[::-1])) # "Python love I"
```
## Day 22: 推导式与相关函数
### 22.1 推导式的概念与语法
- 推导式是一种简洁的for循环写法用于生成新的容器列表、集合、字典
- 基本语法:
- 列表推导式:[表达式 for 变量 in 可迭代对象]
- 带条件的列表推导式:[表达式 for 变量 in 可迭代对象 if 条件]
- 双分支:[表达式1 if 条件 else 表达式2 for 变量 in 可迭代对象]
#### 示例:
```python
# 普通for循环
lst = [1,2,3,4,5,6,7,8,9]
newlst = []
for item in lst:
newlst.append(item * 100)
print(newlst) # [100, 200, ..., 900]
# 列表推导式
print([item * 100 for item in lst])
# 带条件的列表推导式
print([val for val in lst if val % 2 == 0]) # [2, 4, 6, 8]
# 双分支
print([True if val > 5 else False for val in lst]) # [False, False, ..., True]
```
### 22.2 集合推导式与字典推导式
- 集合推导式:用大括号包裹,生成集合
```python
set1 = {1,2,3,4,5,6,7,8,9}
newset = {val * 100 for val in set1}
print(newset)
```
- 字典推导式:用大括号包裹,生成键值对
```python
d = {'zhangsan':70, 'lisi':69, 'wangwu':60}
newdict = {key: value + 10 for key, value in d.items()}
print(newdict) # {'zhangsan': 80, 'lisi': 79, 'wangwu': 70}
```
### 22.3 推导式常见练习
1. 字典转为特定格式字符串列表:
```python
d = {'x': 'A', 'y': 'B', 'z': 'C'}
print([f'{key} = {val}' for key, val in d.items()])
```
2. 列表元素大小写转换:
```python
lst = ["ADDD","dddDD","DDaa","sss"]
print([item.lower() for item in lst])
print([item.upper() for item in lst])
```
3. 组合元组:
```python
print([(x, y) for x in range(0,6) if x%2==0 for y in range(0,6) if y%2!=0])
```
4. 99乘法表
```python
print([f'{i}x{j}={i*j}' for i in range(1,10) for j in range(1,10)])
```
5. 矩阵元素乘积:
```python
M = [[1,2,3], [4,5,6], [7,8,9]]
N = [[2,2,2], [3,3,3], [4,4,4]]
print([M[i][j]*N[i][j] for i in range(3) for j in range(3)])
print([[M[i][j]*N[i][j] for i in range(3)] for j in range(3)])
```
### 22.4 enumerate和zip函数
- enumerate为可迭代对象生成索引号和元素的元组
```python
lst = ['apple','banana','cherry']
print([val for val in enumerate(lst)]) # [(0, 'apple'), (1, 'banana'), (2, 'cherry')]
```
- zip将多个可迭代对象按顺序配对成元组
```python
list1 = [1,2,3,4,5]
list2 = ['a','b','c','d']
list3 = ['A','B','C']
print([val for val in zip(list1, list2, list3)]) # [(1, 'a', 'A'), (2, 'b', 'B'), (3, 'c', 'C')]
```
## Day 23: 函数基础
### 23.1 函数的概念与定义
- 函数是一段可重复使用的代码块,用于执行特定任务
- 函数定义语法:
```python
def 函数名(参数1, 参数2, ...):
函数体
return 返回值
```
示例代码:
```python
# 无参数无返回值的函数
def say_hello():
print("Hello, World!")
# 有参数有返回值的函数
def add(a, b):
return a + b
# 调用函数
say_hello() # 输出Hello, World!
result = add(3, 5)
print(result) # 输出8
```
### 23.2 函数的参数
1. 位置参数:
```python
def greet(name, age):
print(f"你好,{name},你今年{age}岁了")
greet("张三", 18) # 参数按顺序传递
```
2. 默认参数:
```python
def greet(name, age=18):
print(f"你好,{name},你今年{age}岁了")
greet("张三") # 使用默认年龄
greet("李四", 20) # 覆盖默认年龄
```
3. 关键字参数:
```python
def greet(name, age):
print(f"你好,{name},你今年{age}岁了")
greet(age=20, name="王五") # 使用参数名指定值
```
4. 可变参数:
```python
# *args接收任意数量的位置参数
def sum_numbers(*args):
return sum(args)
print(sum_numbers(1, 2, 3, 4)) # 输出10
# **kwargs接收任意数量的关键字参数
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="张三", age=18, city="北京")
```
### 23.3 函数的返回值
1. 单个返回值:
```python
def square(x):
return x * x
result = square(5)
print(result) # 输出25
```
2. 多个返回值:
```python
def get_circle_info(radius):
area = 3.14 * radius * radius
perimeter = 2 * 3.14 * radius
return area, perimeter
area, perimeter = get_circle_info(5)
print(f"面积:{area}, 周长:{perimeter}")
```
3. 无返回值:
```python
def print_message():
print("这是一个消息")
# 没有return语句默认返回None
```
### 23.4 函数的作用域
1. 局部变量:
```python
def test():
x = 10 # 局部变量
print(x)
test()
# print(x) # 错误x未定义
```
2. 全局变量:
```python
x = 100 # 全局变量
def test():
print(x) # 可以访问全局变量
test()
print(x) # 可以访问全局变量
```
3. global关键字
```python
x = 100
def test():
global x # 声明使用全局变量
x = 200 # 修改全局变量
print(x)
test()
print(x) # 输出200
```
### 23.5 函数的高级特性
1. 函数作为参数:
```python
def apply_operation(x, y, operation):
return operation(x, y)
def add(a, b):
return a + b
def multiply(a, b):
return a * b
print(apply_operation(5, 3, add)) # 输出8
print(apply_operation(5, 3, multiply)) # 输出15
```
2. lambda表达式
```python
# 使用lambda定义匿名函数
square = lambda x: x * x
print(square(5)) # 输出25
# 在函数中使用lambda
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x * x, numbers))
print(squared) # 输出:[1, 4, 9, 16, 25]
```
3. 函数装饰器:
```python
def log_function_call(func):
def wrapper(*args, **kwargs):
print(f"调用函数:{func.__name__}")
return func(*args, **kwargs)
return wrapper
@log_function_call
def add(a, b):
return a + b
print(add(3, 5)) # 输出调用函数add 8
```
## Day 24: 函数进阶应用
### 24.1 递归函数
- 递归是函数调用自身的过程
- 递归函数必须包含基本情况(终止条件)和递归情况
示例代码:
```python
# 计算阶乘
def factorial(n):
if n == 0 or n == 1: # 基本情况
return 1
else: # 递归情况
return n * factorial(n - 1)
print(factorial(5)) # 输出120
# 斐波那契数列
def fibonacci(n):
if n <= 1: # 基本情况
return n
else: # 递归情况
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出55
```
### 24.2 闭包
- 闭包是一个函数,它记住了创建时的环境变量
- 闭包可以访问外部函数的变量
示例代码:
```python
def create_counter():
count = 0 # 外部函数的变量
def counter():
nonlocal count # 声明使用外部变量
count += 1
return count
return counter
# 创建计数器
counter = create_counter()
print(counter()) # 输出1
print(counter()) # 输出2
print(counter()) # 输出3
```
### 24.3 生成器函数
- 使用yield关键字创建生成器
- 生成器可以逐个产生值,而不是一次性生成所有值
示例代码:
```python
def number_generator(n):
for i in range(n):
yield i
# 使用生成器
gen = number_generator(5)
for num in gen:
print(num) # 输出0 1 2 3 4
# 生成器表达式
squares = (x*x for x in range(5))
print(list(squares)) # 输出:[0, 1, 4, 9, 16]
```
### 24.4 函数式编程
1. map函数
```python
# 将函数应用于可迭代对象的每个元素
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # 输出:[1, 4, 9, 16, 25]
```
2. filter函数
```python
# 过滤可迭代对象中的元素
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # 输出:[2, 4, 6, 8, 10]
```
3. reduce函数
```python
from functools import reduce
# 将函数应用于可迭代对象的所有元素,返回单个值
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 输出120
```
### 24.5 函数的高级应用
1. 函数缓存:
```python
from functools import lru_cache
@lru_cache(maxsize=128)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10)) # 输出55
```
2. 函数参数检查:
```python
def validate_input(func):
def wrapper(*args, **kwargs):
for arg in args:
if not isinstance(arg, (int, float)):
raise TypeError("参数必须是数字")
return func(*args, **kwargs)
return wrapper
@validate_input
def add(a, b):
return a + b
print(add(1, 2)) # 输出3
# print(add("1", 2)) # 引发TypeError
```
3. 函数计时器:
```python
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数 {func.__name__} 执行时间:{end_time - start_time:.4f} 秒")
return result
return wrapper
@timer
def slow_function():
time.sleep(1)
return "完成"
print(slow_function()) # 输出:函数 slow_function 执行时间1.0000 秒
```
### 24.6 函数的最佳实践
1. 函数命名规范:
```python
# 使用小写字母和下划线
def calculate_average():
pass
# 动词开头
def get_user_info():
pass
# 描述性名称
def convert_temperature():
pass
```
2. 函数文档字符串:
```python
def calculate_circle_area(radius):
"""
计算圆的面积
参数:
radius (float): 圆的半径
返回:
float: 圆的面积
"""
return 3.14 * radius * radius
```
3. 函数参数默认值:
```python
def create_user(name, age=18, city="北京"):
"""
创建用户信息
参数:
name (str): 用户名
age (int, optional): 年龄默认为18
city (str, optional): 城市,默认为北京
"""
return {"name": name, "age": age, "city": city}
```
## Day 25: 模块和包
### 25.1 模块的概念
- 模块是一个包含Python代码的文件
- 模块可以包含函数、类和变量
- 使用模块可以组织代码,提高代码的复用性
示例代码:
```python
# math_operations.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
raise ValueError("除数不能为0")
return a / b
```
### 25.2 导入模块
1. 导入整个模块:
```python
import math_operations
result = math_operations.add(5, 3)
print(result) # 输出8
```
2. 导入特定函数:
```python
from math_operations import add, subtract
result = add(5, 3)
print(result) # 输出8
```
3. 使用别名:
```python
import math_operations as mo
from math_operations import add as addition
result = mo.multiply(5, 3)
print(result) # 输出15
sum_result = addition(5, 3)
print(sum_result) # 输出8
```
### 25.3 内置模块
1. math模块
```python
import math
print(math.pi) # 输出3.141592653589793
print(math.sqrt(16)) # 输出4.0
print(math.pow(2, 3)) # 输出8.0
```
2. random模块
```python
import random
print(random.random()) # 输出0到1之间的随机数
print(random.randint(1, 10)) # 输出1到10之间的随机整数
print(random.choice(['apple', 'banana', 'orange'])) # 随机选择一个元素
```
3. datetime模块
```python
from datetime import datetime, timedelta
now = datetime.now()
print(now) # 输出当前时间
future = now + timedelta(days=7)
print(future) # 输出7天后的时间
```
### 25.4 包的概念
- 包是一个包含多个模块的目录
- 包必须包含一个`__init__.py`文件
- 包可以组织相关的模块
示例结构:
```
my_package/
__init__.py
math_operations.py
string_operations.py
utils.py
```
### 25.5 创建和使用包
1. 创建包:
```python
# my_package/__init__.py
from .math_operations import add, subtract
from .string_operations import reverse_string
# my_package/math_operations.py
def add(a, b):
return a + b
def subtract(a, b):
return a - b
# my_package/string_operations.py
def reverse_string(text):
return text[::-1]
```
2. 使用包:
```python
from my_package import add, reverse_string
print(add(5, 3)) # 输出8
print(reverse_string("Hello")) # 输出olleH
```
### 25.6 模块和包的最佳实践
1. 模块命名规范:
```python
# 使用小写字母和下划线
math_operations.py
string_utils.py
data_processing.py
```
2. 包的结构:
```
project/
package1/
__init__.py
module1.py
module2.py
package2/
__init__.py
module3.py
module4.py
main.py
```
3. 相对导入:
```python
# 在包内使用相对导入
from .module1 import function1
from ..package2.module3 import function3
```
4. 模块文档:
```python
"""
这是一个数学运算模块
这个模块提供了基本的数学运算功能,包括:
- 加法
- 减法
- 乘法
- 除法
"""
def add(a, b):
"""
计算两个数的和
参数:
a (int/float): 第一个数
b (int/float): 第二个数
返回:
int/float: 两个数的和
"""
return a + b
```
### 25.7 常用第三方包
1. requestsHTTP请求
```python
import requests
response = requests.get('https://api.example.com/data')
print(response.json())
```
2. pandas数据处理
```python
import pandas as pd
df = pd.DataFrame({
'name': ['张三', '李四', '王五'],
'age': [20, 25, 30]
})
print(df)
```
3. numpy科学计算
```python
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr.mean()) # 计算平均值
print(arr.std()) # 计算标准差
```
## Day 26: 面向对象编程基础
### 26.1 类和对象的概念
- 类是一个模板,用于创建对象
- 对象是类的实例,具有属性和方法
- 属性是对象的特征
- 方法是对象的行为
示例代码:
```python
class Person:
# 类属性
species = "人类"
# 初始化方法
def __init__(self, name, age):
# 实例属性
self.name = name
self.age = age
# 实例方法
def introduce(self):
return f"我叫{self.name},今年{self.age}岁"
# 创建对象
person1 = Person("张三", 20)
person2 = Person("李四", 25)
# 访问属性和方法
print(person1.name) # 输出:张三
print(person1.introduce()) # 输出我叫张三今年20岁
print(Person.species) # 输出:人类
```
### 26.2 类的属性
1. 类属性:
```python
class Student:
# 类属性
school = "第一中学"
total_students = 0
def __init__(self, name):
self.name = name
Student.total_students += 1
# 访问类属性
print(Student.school) # 输出:第一中学
# 创建对象
student1 = Student("张三")
student2 = Student("李四")
print(Student.total_students) # 输出2
```
2. 实例属性:
```python
class Car:
def __init__(self, brand, model, year):
self.brand = brand
self.model = model
self.year = year
self.speed = 0 # 初始速度
def accelerate(self):
self.speed += 10
def brake(self):
self.speed -= 5
# 创建对象
car = Car("丰田", "卡罗拉", 2020)
print(car.brand) # 输出:丰田
car.accelerate()
print(car.speed) # 输出10
```
### 26.3 类的方法
1. 实例方法:
```python
class Rectangle:
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
rect = Rectangle(5, 3)
print(rect.area()) # 输出15
print(rect.perimeter()) # 输出16
```
2. 类方法:
```python
class MathUtils:
pi = 3.14159
@classmethod
def circle_area(cls, radius):
return cls.pi * radius * radius
@classmethod
def circle_perimeter(cls, radius):
return 2 * cls.pi * radius
print(MathUtils.circle_area(5)) # 输出78.53975
```
3. 静态方法:
```python
class StringUtils:
@staticmethod
def is_palindrome(text):
return text == text[::-1]
@staticmethod
def count_words(text):
return len(text.split())
print(StringUtils.is_palindrome("level")) # 输出True
print(StringUtils.count_words("Hello World")) # 输出2
```
### 26.4 封装
1. 私有属性和方法:
```python
class BankAccount:
def __init__(self, account_number, balance):
self.__account_number = account_number # 私有属性
self.__balance = balance
def __validate_amount(self, amount): # 私有方法
return amount > 0
def deposit(self, amount):
if self.__validate_amount(amount):
self.__balance += amount
return True
return False
def get_balance(self):
return self.__balance
account = BankAccount("12345", 1000)
account.deposit(500)
print(account.get_balance()) # 输出1500
```
2. 属性装饰器:
```python
class Person:
def __init__(self, name, age):
self.__name = name
self.__age = age
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise ValueError("名字必须是字符串")
self.__name = value
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if not isinstance(value, int) or value < 0:
raise ValueError("年龄必须是正整数")
self.__age = value
person = Person("张三", 20)
print(person.name) # 输出:张三
person.name = "李四"
print(person.name) # 输出:李四
```
### 26.5 继承
1. 单继承:
```python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
class Dog(Animal):
def speak(self):
return f"{self.name}说:汪汪!"
class Cat(Animal):
def speak(self):
return f"{self.name}说:喵喵!"
dog = Dog("旺财")
cat = Cat("咪咪")
print(dog.speak()) # 输出:旺财说:汪汪!
print(cat.speak()) # 输出:咪咪说:喵喵!
```
2. 多继承:
```python
class Flyable:
def fly(self):
return "我能飞"
class Swimmable:
def swim(self):
return "我能游泳"
class Duck(Flyable, Swimmable):
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name}说:嘎嘎!"
duck = Duck("唐老鸭")
print(duck.speak()) # 输出:唐老鸭说:嘎嘎!
print(duck.fly()) # 输出:我能飞
print(duck.swim()) # 输出:我能游泳
```
### 26.6 多态
```python
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def print_area(shape):
print(f"面积是:{shape.area()}")
# 多态示例
circle = Circle(5)
rectangle = Rectangle(4, 6)
print_area(circle) # 输出面积是78.5
print_area(rectangle) # 输出面积是24
```
## Day 27: 面向对象编程进阶
### 27.1 抽象类和接口
1. 抽象类:
```python
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius * self.radius
def perimeter(self):
return 2 * 3.14 * self.radius
# 不能直接实例化抽象类
# shape = Shape() # 会报错
circle = Circle(5)
print(circle.area()) # 输出78.5
```
2. 接口(通过抽象类实现):
```python
from abc import ABC, abstractmethod
class PaymentMethod(ABC):
@abstractmethod
def pay(self, amount):
pass
class CreditCard(PaymentMethod):
def pay(self, amount):
return f"使用信用卡支付{amount}元"
class Alipay(PaymentMethod):
def pay(self, amount):
return f"使用支付宝支付{amount}元"
# 使用接口
def process_payment(payment_method, amount):
return payment_method.pay(amount)
card = CreditCard()
alipay = Alipay()
print(process_payment(card, 100)) # 输出使用信用卡支付100元
print(process_payment(alipay, 200)) # 输出使用支付宝支付200元
```
### 27.2 魔术方法
1. 基本魔术方法:
```python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
def __repr__(self):
return f"Person('{self.name}', {self.age})"
def __len__(self):
return len(self.name)
def __bool__(self):
return self.age >= 18
person = Person("张三", 20)
print(str(person)) # 输出Person(name=张三, age=20)
print(repr(person)) # 输出Person('张三', 20)
print(len(person)) # 输出2
print(bool(person)) # 输出True
```
2. 运算符魔术方法:
```python
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y)
def __mul__(self, scalar):
return Vector(self.x * scalar, self.y * scalar)
def __str__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 + v2) # 输出Vector(4, 6)
print(v2 - v1) # 输出Vector(2, 2)
print(v1 * 2) # 输出Vector(2, 4)
```
### 27.3 描述符
1. 属性描述符:
```python
class ValidString:
def __init__(self, minlen=0, maxlen=None):
self.minlen = minlen
self.maxlen = maxlen
def __get__(self, instance, owner):
return instance.__dict__.get(self.name)
def __set__(self, instance, value):
if not isinstance(value, str):
raise TypeError("值必须是字符串")
if len(value) < self.minlen:
raise ValueError(f"字符串长度不能小于{self.minlen}")
if self.maxlen and len(value) > self.maxlen:
raise ValueError(f"字符串长度不能大于{self.maxlen}")
instance.__dict__[self.name] = value
def __set_name__(self, owner, name):
self.name = name
class User:
name = ValidString(minlen=2, maxlen=20)
email = ValidString(minlen=5, maxlen=50)
def __init__(self, name, email):
self.name = name
self.email = email
user = User("张三", "zhangsan@example.com")
print(user.name) # 输出:张三
print(user.email) # 输出zhangsan@example.com
```
### 27.4 元类
1. 基本元类:
```python
class MetaLogger(type):
def __new__(cls, name, bases, attrs):
print(f"创建类:{name}")
return super().__new__(cls, name, bases, attrs)
def __init__(cls, name, bases, attrs):
print(f"初始化类:{name}")
super().__init__(name, bases, attrs)
class MyClass(metaclass=MetaLogger):
def __init__(self):
print("初始化实例")
# 创建类时会打印日志
obj = MyClass()
```
2. 单例模式:
```python
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super().__call__(*args, **kwargs)
return cls._instances[cls]
class Database(metaclass=Singleton):
def __init__(self):
print("初始化数据库连接")
def query(self, sql):
return f"执行SQL{sql}"
# 创建多个实例,但只会初始化一次
db1 = Database()
db2 = Database()
print(db1 is db2) # 输出True
```
### 27.5 设计模式
1. 工厂模式:
```python
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "汪汪!"
class Cat(Animal):
def speak(self):
return "喵喵!"
class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError("未知的动物类型")
# 使用工厂创建对象
factory = AnimalFactory()
dog = factory.create_animal("dog")
cat = factory.create_animal("cat")
print(dog.speak()) # 输出:汪汪!
print(cat.speak()) # 输出:喵喵!
```
2. 观察者模式:
```python
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self, message):
for observer in self._observers:
observer.update(message)
class Observer:
def update(self, message):
pass
class NewsAgency(Subject):
def publish_news(self, news):
self.notify(news)
class NewsChannel(Observer):
def __init__(self, name):
self.name = name
def update(self, message):
print(f"{self.name}收到新闻:{message}")
# 使用观察者模式
agency = NewsAgency()
channel1 = NewsChannel("CCTV")
channel2 = NewsChannel("BBC")
agency.attach(channel1)
agency.attach(channel2)
agency.publish_news("重大新闻!")
```
### 27.6 最佳实践
1. 组合优于继承:
```python
class Engine:
def start(self):
return "引擎启动"
class Wheel:
def rotate(self):
return "轮子转动"
class Car:
def __init__(self):
self.engine = Engine()
self.wheels = [Wheel() for _ in range(4)]
def start(self):
return self.engine.start()
def drive(self):
return [wheel.rotate() for wheel in self.wheels]
car = Car()
print(car.start()) # 输出:引擎启动
print(car.drive()) # 输出:['轮子转动', '轮子转动', '轮子转动', '轮子转动']
```
2. 依赖注入:
```python
class Database:
def query(self, sql):
return f"执行SQL{sql}"
class UserService:
def __init__(self, database):
self.database = database
def get_user(self, user_id):
return self.database.query(f"SELECT * FROM users WHERE id = {user_id}")
# 使用依赖注入
db = Database()
user_service = UserService(db)
print(user_service.get_user(1))
```