第1章 Python基础
本章目标:掌握 Python 最常见的数据类型、字符串与编码、列表与元组、条件判断、循环、字典与集合等基础内容。
1. Python代码的基本特点
- Python 使用缩进组织代码块,而不是大括号
- 一般约定使用 4 个空格 作为一级缩进
- 变量名推荐见名知意,遵循
snake_case风格
2. 数据类型和变量
2.1 整数 int
- Python 的整数没有固定大小限制
- 数字中可以用
_分隔,便于阅读
num = 10_000_000
print(num)
2.2 浮点数 float
- 浮点数就是带小数的数据
- 可以使用科学计数法
a = 3.14
b = 1.23e9
print(a, b)
[!tip] 注意
浮点数在计算机中是近似表示的,因此某些运算结果可能存在精度误差。
2.3 字符串 str
- 字符串可以用单引号或双引号包起来
\用于转义- 常见转义字符:
\n:换行\t:制表符
r'...'表示原始字符串,默认不转义'''...'''或"""..."""可以表示多行字符串
print('I\'m "OK"!')
print(r'c:\new\test')
print('''line1
line2
line3''')
2.4 布尔值 bool
- 只有两个值:
True和False - 常见逻辑运算:
andornot
print(3 > 2 and 2 > 1)
print(not False)
2.5 空值 None
None表示“空”或“没有值”None不是0,也不是空字符串''
x = None
print(x)
2.6 变量
变量名规则:
- 由字母、数字、下划线组成
- 不能以数字开头
- 区分大小写
当我们写:
a = 'ABC'
可以理解为:
- 创建字符串对象
'ABC' - 创建变量
a - 让
a指向字符串对象'ABC'
再看:
a = 'ABC'
b = a
a = 'XYZ'
print(b)
输出:
ABC
说明:b 仍然指向原来的 'ABC',而 a 改为指向新的 'XYZ'。
2.7 常量
Python 没有真正意义上“不能改”的常量,但通常使用全大写变量名表示常量:
PI = 3.1415926
这只是约定,不是语法强制。
2.8 小练习
n = 123
f = 456.789
s1 = 'Hello, world'
s2 = 'Hello, \'Adam\''
s3 = r'Hello, "Bart"'
s4 = r'''Hello,
Bob!'''
print(n)
print(f)
print(s1)
print(s2)
print(s3)
print(s4)
2.9 小结
- Python 中一切数据都可以看作对象
- 变量本质上是对象的引用
- 常见基础类型:
int、float、str、bool、None
3. 字符串和编码
3.1 字符编码的基本概念
常见发展过程:
ASCII -> Unicode -> UTF-8 / UTF-16 / UTF-32
ASCII:早期英文编码Unicode:统一的字符标准,为每个字符分配编号UTF-8:把 Unicode 字符编码成字节的一种方式,属于可变长编码
UTF-8 的优点:
- 兼容 ASCII
- 英文占用空间小
- 跨平台和网络传输非常常用
[!important] 更准确的说法
程序内部通常按 Unicode 文本来处理字符串;在保存文件或网络传输时,需要把文本编码成字节,UTF-8 是最常见的选择,但不是唯一选择。
3.2 Python中的 str 和 bytes
在 Python 3 中:
str表示文本bytes表示字节数据
s = 'ABC'
b = b'ABC'
print(s)
print(b)
3.3 ord() 和 chr()
ord():字符转整数编码chr():整数编码转字符
print(ord('A'))
print(ord('中'))
print(chr(66))
print(chr(25991))
3.4 编码 encode()
str 转 bytes:
print('ABC'.encode('ascii'))
print('中文'.encode('utf-8'))
错误示例:
# print('中文'.encode('ascii'))
原因:ASCII 编码无法表示中文字符。
3.5 解码 decode()
bytes 转 str:
print(b'ABC'.decode('ascii'))
print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
3.6 len() 的区别
- 对
str:统计字符个数 - 对
bytes:统计字节个数
print(len('ABC'))
print(len('中文'))
print(len(b'ABC'))
print(len('中文'.encode('utf-8')))
3.7 源码编码
如果源码中包含中文,文件建议保存为 UTF-8。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
说明:
- 第 1 行常见于 Linux / macOS 可执行脚本
- 第 2 行用于声明源码编码
- 在 Python 3 中,UTF-8 已经是常见默认编码,但理解这两行的含义仍然有帮助
3.8 小结
str是文本,bytes是字节encode():文本转字节decode():字节转文本- UTF-8 很常用,但不是唯一编码方案
4. 字符串格式化
Python 中常见的格式化方式有 3 种:
%格式化format()f-string
4.1 % 格式化
常见占位符:
| 占位符 | 含义 |
|---|---|
%d |
整数 |
%f |
浮点数 |
%s |
字符串 |
%x |
十六进制整数 |
print('Hi %s, your score is %d' % ('Bart', 100))
print('%2d-%02d' % (3, 1))
print('%.2f' % 3.1415926)
如果 % 只是普通字符,要写成 %%:
print('growth rate: %d %%' % 7)
4.2 format()
{} 是占位符,format() 会把值填进去。
print('Hello, {}'.format('Tom'))
print('我叫{0},今年{1}岁'.format('小明', 18))
print('圆周率约等于{:.2f}'.format(3.1415926))
print('Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.12345))
说明:
{0}表示第 1 个参数{1:.1f}表示第 2 个参数保留 1 位小数- 最后面的
%只是普通字符,不参与运算
4.3 f-string
这是现在最推荐的方式,可读性最好。
name = 'Bart'
score = 95.678
print(f'Hello, {name}')
print(f'成绩是 {score:.1f}')
print(f'12 * 12 = {12 * 12}')
4.4 小结
- 老代码常见
% format()更灵活- 日常开发最常用
f-string
5. 使用 list 和 tuple
5.1 列表 list
list 是一种有序、可变的容器。
classmates = ['Michael', 'Bob', 'Tracy']
print(classmates)
常用操作:
len(my_list):获取元素个数my_list[i]:按索引取值my_list[-1]:取最后一个元素append(x):追加元素insert(i, x):插入元素pop():删除末尾元素pop(i):删除指定位置元素
nums = [1, 2, 3]
nums.append(4)
nums.insert(1, 99)
nums.pop()
print(nums)
5.2 元组 tuple
tuple 是一种有序、不可变的容器。
classmates = ('Michael', 'Bob', 'Tracy')
特点:
- 可以取值
- 不能修改元素指向
- 更适合表达“这组数据不该被改”
空 tuple 和单元素 tuple
t1 = ()
t2 = (1,)
注意:只有一个元素时,必须写逗号,否则会被当成普通括号。
“看起来可变”的 tuple
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
print(t)
这不是 tuple 本身变了,而是 tuple 里的 list 变了。
所以更准确地说:
tuple 不可变,指的是 tuple 中每个位置绑定到哪个对象不能变。
5.3 list 和 tuple 对比
| 类型 | 是否有序 | 是否可变 | 常见用途 |
|---|---|---|---|
list |
是 | 是 | 存储可修改的数据集合 |
tuple |
是 | 否 | 存储不希望被修改的数据 |
6. 条件判断
最基本结构:
age = int(input('Please input your age: '))
if age < 18:
print('Not an adult')
else:
print('Adult')
说明:
input()得到的是字符串- 如果要和数字比较,通常需要先用
int()转换
多分支示例:
score = 78
if score >= 90:
print('A')
elif score >= 80:
print('B')
elif score >= 60:
print('C')
else:
print('D')
7. 模式匹配 match
[!tip] 注意
match ... case是 Python 3.10+ 的语法。
7.1 简单匹配
score = 'B'
match score:
case 'A':
print('Score is A.')
case 'B':
print('Score is B.')
case 'C':
print('Score is C.')
case _:
print('Score is ???')
可以把它理解为更强大的 switch-case。
7.2 带条件的匹配
age = 15
match age:
case x if x < 10:
print(f'< 10 years old: {x}')
case 10:
print('10 years old.')
case 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18:
print('11~18 years old.')
case 19:
print('19 years old.')
case _:
print('not sure.')
7.3 匹配列表
args = ['gcc', 'hello.c', 'world.c']
match args:
case ['gcc']:
print('gcc: missing source file(s).')
case ['gcc', file1, *files]:
print('gcc compile: ' + file1 + ', ' + ', '.join(files))
case ['clean']:
print('clean')
case _:
print('invalid command.')
8. 循环
8.1 for 循环
total = 0
for x in range(101):
total = total + x
print(total)
说明:
range(101)表示0到100- 不建议把变量命名为
sum,因为会覆盖 Python 内置函数sum()
8.2 while 循环
total = 0
n = 1
while n <= 100:
total = total + n
n = n + 1
print(total)
8.3 break
break 用于提前结束整个循环。
n = 1
while n <= 10:
if n == 5:
break
print(n)
n += 1
8.4 continue
continue 用于跳过本次循环,进入下一次循环。
for x in range(1, 6):
if x == 3:
continue
print(x)
[!tip] 建议
break和continue能少用就少用,循环逻辑会更清晰。
9. 使用 dict 和 set
9.1 字典 dict
dict 是一种键值对结构,查找速度快。
d = {'Jack': 95, 'Bob': 90, 'Cathy': 89}
print(d['Jack'])
常用操作:
- 通过 key 取值:
d['Jack'] - 新增或修改:
d[key] = value - 判断 key 是否存在:
'a' in d - 安全取值:
d.get('a') - 带默认值取值:
d.get('a', -1) - 删除一个 key:
d.pop('a') - 使用
del d['a']删除 - 清空字典:
d.clear()
d = {'name': 'Tom'}
d['age'] = 18
d['name'] = 'Bob'
print(d)
d = {'name': 'Tom', 'age': 18}
print(d.pop('age'))
print(d)
为什么 dict 的 key 必须可哈希
字典底层依赖哈希表快速定位数据,因此:
- key 必须可哈希
- key 通常也必须是不可变对象
例如这些通常可以作为 key:
intstrtuple(前提是内部元素也都可哈希)
这些不能作为 key:
listdictset
9.2 集合 set
set 是一种无序、元素不重复的集合。
s = {1, 2, 3}
print(s)
也可以这样创建:
s = set([1, 2, 3])
print(s)
常用操作:
add(x):添加元素remove(x):删除元素in:判断元素是否存在
s = {1, 2, 3}
s.add(4)
s.remove(2)
print(s)
集合运算:
s1 = {1, 2, 3}
s2 = {2, 3, 4}
print(s1 & s2) # 交集
print(s1 | s2) # 并集
为什么 set 里不能放可变对象
因为 set 和 dict 一样,底层也依赖哈希值,所以:
set的元素必须可哈希- 因此通常不能放
list、dict、普通set
可以放的例子:
s = {1, 'abc', (1, 2)}
print(s)
9.3 不可变对象的理解
看这个例子:
a = 'abc'
print(a.replace('a', 'A'))
print(a)
输出:
Abc
abc
说明:
replace()没有修改原字符串- 它返回了一个新的字符串
所以,不可变对象的意思不是“不能调用方法”,而是:
对象一旦创建,其内容本身不能被原地修改。
9.4 可变性与可哈希速查表
| 类型 | 是否可变 | 是否可哈希 | 能否作为 dict 的 key |
能否放入 set |
|---|---|---|---|---|
int |
否 | 是 | 能 | 能 |
str |
否 | 是 | 能 | 能 |
list |
是 | 否 | 不能 | 不能 |
tuple |
否 | 通常是 | 通常能 | 通常能 |
dict |
是 | 否 | 不能 | 不能 |
set |
是 | 否 | 不能 | 不能 |
frozenset |
否 | 是 | 能 | 能 |
[!tip] 注意
tuple只有在其所有元素都可哈希时,才可以作为dict的 key 或放入set。
9.5 小结
dict本身可变,但 key 必须可哈希set本身可变,但元素必须可哈希- value 可以是可变对象,但 key 不行
10. 本章总结
本章需要重点掌握:
- 基础类型:
int、float、str、bool、None - 字符串与字节:
str、bytes、encode()、decode() - 三种格式化方式:
%、format()、f-string - 容器类型:
list、tuple、dict、set - 流程控制:
if、match、for、while - 可变对象、不可变对象、可哈希对象
11. 练习题
11.1 基础题
- 定义一个整数、一个浮点数、一个字符串,并分别打印它们。
- 写出下面字符串的输出结果:
print('I\'m learning Python\nVery good!')
- 说出
str和bytes的区别。 - 使用
ord()输出'A'和'中'的编码值。 - 将字符串
'hello'编码为bytes,再解码回来。
11.2 字符串格式化题
- 使用
%格式化输出:
My name is Tom, age is 18
- 使用
format()格式化输出一个浮点数,保留两位小数。 - 使用
f-string输出:
小明的成绩是 92.5
11.3 容器题
- 创建一个包含 5 个整数的
list,输出第 1 个和最后 1 个元素。 - 向
list中追加一个元素,再删除一个元素。 - 创建一个
tuple,并说明为什么单元素 tuple 要写成(1,)。 - 创建一个
dict,包含name和age两个键值对,并输出其中一个值。 - 创建两个
set,分别求交集和并集。
11.4 条件与循环题
- 输入一个分数,判断输出“优秀 / 良好 / 及格 / 不及格”。
- 使用
for循环计算1 + 2 + ... + 100。 - 使用
while循环输出 1 到 10。 - 写一个循环,输出 1 到 20 中的所有奇数。
- 写一个循环,遇到数字 7 时停止。
11.5 思考题
- 为什么
dict的 key 不能用list? - 为什么
set里不能直接放dict? - 为什么说
tuple“通常”可哈希,而不是“永远”可哈希? - 为什么说 UTF-8 很常用,但不是所有场景都必须用 UTF-8?
12. 练习小项目:学生成绩管理器
12.1 项目目标
用本章学过的知识,写一个命令行小程序,管理若干学生成绩。
12.2 功能要求
至少实现以下功能:
- 添加学生成绩
- 查询某个学生成绩
- 修改学生成绩
- 删除学生成绩
- 显示所有学生成绩
- 统计最高分、最低分、平均分
12.3 提示
- 可以使用
dict存储数据:
scores = {
'Tom': 95,
'Bob': 82
}
- 可以使用
while True做菜单循环 - 可以用
if/elif/else处理不同操作 - 输入的分数记得用
int()转换
12.4 进阶要求
如果你想多练一点,可以继续加:
- 判断输入的分数是否在
0~100 - 显示成绩等级(A / B / C / D)
- 防止添加重名学生
- 使用
set统计出现过的成绩等级
12.5 推荐菜单形式
1. 添加成绩
2. 查询成绩
3. 修改成绩
4. 删除成绩
5. 显示全部
6. 统计信息
0. 退出程序
12.6 这个项目会练到什么
input()- 类型转换
if/elif/elsewhiledictset- 字符串格式化
项目实现见:学生成绩管理器
浙公网安备 33010602011771号