一、背景
上一篇整理了 Python 中的字符串、列表、元组、集合和字典。
这一篇继续整理 Python 中的流程控制、循环和迭代器。对应的练习代码主要包括:
32循环技巧.py
33分支语句.py
34while循环.py
35range函数.py
36for循环.py
37Break与continue语句.py
38迭代器.py
39生成器.py
这部分内容看起来比较基础,但是实际写程序时非常常用。
比如:
- 根据不同条件走不同逻辑
- 遍历列表、字典、字符串
- 跳过某些不需要处理的数据
- 在找到目标数据后提前退出循环
- 使用迭代器或生成器按需处理数据
二、if 分支语句
if 用来做条件判断。基本语法如下:
if 条件1:
代码块1
elif 条件2:
代码块2
else:
代码块3
例如:
num = 5
if num == 3:
print("boss")
elif num == 2:
print("user")
elif num == 1:
print("worker")
elif num < 0:
print("error")
else:
print("roadman")
这里需要注意几点:
- 条件后面要写冒号
: - Python 使用缩进表示代码块
- 同一代码块的缩进必须保持一致
if可以有多个elifelse不是必须的
三、Python 中的真假值
在 Python 中,很多对象都可以直接放到条件判断中。
下面这些值会被认为是 False:
| 值 | 说明 |
|---|---|
False |
布尔假 |
None |
空值 |
0 |
数字 0 |
"" |
空字符串 |
[] |
空列表 |
{} |
空字典 |
set() |
空集合 |
() |
空元组 |
其他大多数值会被认为是 True。
例如:
names = []
if names:
print("列表中有数据")
else:
print("列表为空")
这种写法比 if len(names) > 0: 更简洁。
四、多个条件组合
可以使用 and、or、not 组合多个条件。
1. and
and 表示多个条件都成立。
num = 9
if num >= 0 and num <= 10:
print("num 在 0 到 10 之间")
也可以写得更符合 Python 风格:
num = 9
if 0 <= num <= 10:
print("num 在 0 到 10 之间")
2. or
or 表示只要有一个条件成立。
num = 12
if num < 0 or num > 10:
print("num 不在 0 到 10 之间")
3. not
not 表示取反。
names = []
if not names:
print("列表为空")
五、Python 没有 switch-case
早期 Python 中没有 switch-case 语句,通常使用 if...elif...else 或字典映射来替代。
例如:
role = "admin"
if role == "admin":
print("管理员")
elif role == "user":
print("普通用户")
else:
print("未知角色")
也可以使用字典映射:
role = "admin"
role_map = {
"admin": "管理员",
"user": "普通用户",
"guest": "访客",
}
print(role_map.get(role, "未知角色"))
如果后续使用的是 Python 3.10 之后的版本,也可以了解 match...case,不过基础阶段先掌握 if...elif...else 更重要。
六、while 循环
while 会在条件成立时重复执行代码。
count = 0
while count < 5:
print("count =", count)
count += 1
执行过程是:
- 判断
count < 5 - 条件成立就执行循环体
- 执行完循环体后再次判断条件
- 条件不成立时退出循环
写 while 时要特别注意循环变量的变化,否则很容易写成死循环。
例如下面这种写法会一直运行:
# count = 0
# while count < 5:
# print(count)
因为 count 没有变化,条件会一直成立。
七、while…else
Python 的循环可以带 else。
count = 0
while count < 5:
print(count, "is less than 5")
count += 1
else:
print(count, "is not less than 5")
这里的 else 会在循环正常结束时执行。
如果循环中通过 break 提前退出,else 不会执行。
count = 0
while count < 5:
if count == 3:
break
print(count)
count += 1
else:
print("正常结束")
这个例子中,count == 3 时触发 break,所以不会打印 正常结束。
八、range 函数
range() 常用于生成一段整数序列。
1. 只指定结束值
for x in range(3):
print(x)
输出:
0
1
2
range(3) 表示从 0 到 3,但是不包含 3。
2. 指定开始和结束
for x in range(4, 8):
print(x)
输出:
4
5
6
7
3. 指定步长
for x in range(0, 30, 5):
print(x)
输出:
0
5
10
15
20
25
range() 的特点是包前不包后,这一点和切片类似。
九、for 循环
for 循环用于遍历可迭代对象,例如字符串、列表、元组、字典、集合等。
1. 遍历字符串
for letter in "Python":
print(letter)
2. 遍历列表
fruits = ["banana", "apple", "mango"]
for fruit in fruits:
print(fruit)
3. 使用 range 遍历索引
fruits = ["banana", "apple", "mango"]
for index in range(len(fruits)):
print(index, fruits[index])
不过如果既要索引又要值,更推荐使用 enumerate()。
fruits = ["banana", "apple", "mango"]
for index, fruit in enumerate(fruits):
print(index, fruit)
十、循环技巧
练习代码中整理了几个常用循环技巧,这些写法在实际开发中很常见。
1. items 遍历字典
user = {
"name": "xiaoming",
"age": 18,
}
for key, value in user.items():
print(key, value)
2. enumerate 获取索引和值
names = ["xiaoming", "xiaohong", "xiaogang"]
for index, name in enumerate(names):
print(index, name)
3. zip 同时遍历多个序列
names = ["xiaoming", "xiaohong", "xiaogang"]
ages = [18, 16, 19]
for name, age in zip(names, ages):
print(name, age)
需要注意:zip() 会按最短的序列结束。
names = ["a", "b", "c"]
ages = [10, 20]
print(list(zip(names, ages)))
# [('a', 10), ('b', 20)]
4. sorted 排序后遍历
nums = [1, 4, 3, 6, 5, 7]
for num in sorted(nums):
print(num)
如果需要倒序:
for num in sorted(nums, reverse=True):
print(num)
十一、break 和 continue
break 和 continue 都用于控制循环流程。
| 语句 | 含义 |
|---|---|
break |
直接结束整个循环 |
continue |
跳过本次循环,进入下一轮 |
1. break
for letter in "Python":
if letter == "h":
break
print(letter)
输出:
P
y
t
遇到 h 后,循环直接结束。
2. continue
for letter in "Python":
if letter == "h":
continue
print(letter)
输出:
P
y
t
o
n
遇到 h 后,只是跳过当前这一轮,后面的 o、n 还会继续处理。
3. 打印 1 到 10 之间的奇数
n = 0
while n < 10:
n += 1
if n % 2 == 0:
continue
print(n)
这里通过 continue 跳过偶数,只打印奇数。
十二、嵌套循环
循环中还可以再写循环。
例如打印乘法组合:
for i in range(1, 4):
for j in range(1, 4):
print(i, "*", j, "=", i * j)
嵌套循环中使用 break 时,只会跳出当前这一层循环。
for i in range(3):
for j in range(3):
if j == 1:
break
print(i, j)
如果嵌套层级太深,代码会变得难读。这种情况下通常需要考虑拆函数。
十三、迭代器
迭代是 Python 中访问集合元素的一种方式。
迭代器有两个核心特点:
- 可以记住当前遍历到的位置
- 只能向前取值,不能回退
可以使用 iter() 创建迭代器,使用 next() 取下一个值。
nums = [1, 2, 3, 4]
it = iter(nums)
print(next(it)) # 1
print(next(it)) # 2
当迭代器没有更多元素时,会抛出 StopIteration。
nums = [1, 2]
it = iter(nums)
print(next(it)) # 1
print(next(it)) # 2
# print(next(it)) # StopIteration
平时我们很少手动写 next(),更多是让 for 循环自动处理。
nums = [1, 2, 3, 4]
for num in iter(nums):
print(num)
for 循环内部会不断调用 next(),并在遇到 StopIteration 时结束循环。
十四、自定义迭代器
如果一个类要作为迭代器使用,需要实现两个方法:
__iter__()__next__()
示例:
class MyNumbers:
def __iter__(self):
self.current = 1
return self
def __next__(self):
if self.current <= 5:
value = self.current
self.current += 1
return value
raise StopIteration
nums = MyNumbers()
for num in nums:
print(num)
输出:
1
2
3
4
5
这里的关键是:当没有数据可取时,要抛出 StopIteration,告诉 Python 迭代已经结束。
十五、生成器
生成器也是一种迭代器。
相比自己写 __iter__() 和 __next__(),生成器写起来更简单。
1. 生成器表达式
把列表推导式的中括号改成小括号,就得到了生成器表达式。
nums = [2 * x for x in range(3)]
print(nums)
# [0, 2, 4]
gen = (2 * x for x in range(3))
print(next(gen)) # 0
print(next(gen)) # 2
print(next(gen)) # 4
列表推导式会一次性生成完整列表,生成器表达式会按需生成数据。
如果数据量很大,生成器更节省内存。
2. yield 生成器函数
函数中只要出现 yield,这个函数调用后返回的就是一个生成器对象。
def count_up_to(max_num):
current = 1
while current <= max_num:
yield current
current += 1
for num in count_up_to(5):
print(num)
输出:
1
2
3
4
5
yield 和 return 不一样。
| 写法 | 含义 |
|---|---|
return |
函数直接结束并返回结果 |
yield |
暂停函数,返回一个值,下次继续从暂停位置往下执行 |
十六、什么时候使用生成器
生成器适合下面这些场景:
- 数据量比较大,不想一次性全部加载到内存
- 数据是逐条产生的
- 只需要遍历一次
- 想把数据生产逻辑写得更清楚
例如模拟逐行读取日志:
def read_lines():
yield "2023-12-09 10:00:00 INFO start"
yield "2023-12-09 10:00:01 INFO running"
yield "2023-12-09 10:00:02 INFO end"
for line in read_lines():
print(line)
后面学习文件读取时,这种思想会经常用到。
十七、总结
这一篇主要整理了流程控制、循环和迭代器。
需要重点记住:
if...elif...else用来处理分支判断- Python 使用缩进表示代码块
while适合条件循环,for适合遍历对象range()常用于生成整数序列break结束循环,continue跳过本次循环enumerate()、zip()、items()是非常常用的循环技巧- 迭代器通过
iter()和next()工作 - 生成器通过
yield或生成器表达式按需产生数据
后面写函数、文件处理、JSON 处理和爬虫时,循环和迭代会一直出现。