tqdm进度条工具
tqdm
是 Python 中一个非常流行的 进度条显示工具库,常用于迭代操作的可视化,比如训练神经网络、批量数据处理等任务。
一、tqdm
是什么?
tqdm
全称是 taqaddum(阿拉伯语,意为“进展”),它会在控制台输出一个带进度条的实时反馈,常用于 for
循环中追踪当前执行状态和速度。
二、常用方法
1. 对普通 for
循环添加进度条
from tqdm import tqdm
for i in tqdm(range(100)):# 模拟耗时任务time.sleep(0.01)
2. 与 DataLoader
搭配(最常见)
from tqdm import tqdm
for batch in tqdm(trainloader):# 处理 batchpass
3. 自定义描述信息
for i in tqdm(range(100), desc="Processing"):time.sleep(0.01)
4. 显示时间与速率信息
tqdm
会自动显示:
- 当前进度
- 已耗时间
- 平均耗时
- 预计剩余时间
例如:
Processing: 45%|██████████████████▋ | 45/100 [00:01<00:01, 34.56it/s]
5. 嵌套进度条(多层循环)
from tqdm import tqdm
for i in tqdm(range(3), desc="Outer loop"):for j in tqdm(range(100), desc="Inner loop", leave=False):time.sleep(0.01)
三、使用注意事项
问题 | 建议 |
---|---|
卡住无响应? | 避免在 Jupyter 中用旧版本 tqdm ,使用 tqdm.notebook 替代 |
速度不准? | 小任务迭代速度快可能导致显示误差大,可加 mininterval=0.5 |
配合 DataLoader 卡顿? | 添加 num_workers=0 测试排查线程冲突 |
重定向被清空? | 若与 print() 频繁混用建议设 tqdm(..., leave=True) |
四、完整代码示例
from tqdm import tqdm
import timeprint("普通进度条演示:")
for i in tqdm(range(50), desc="任务A"):time.sleep(0.02)print("\n嵌套进度条演示:")
for epoch in tqdm(range(2), desc="Epoch"):for batch in tqdm(range(10), desc="Batch", leave=False):time.sleep(0.05)
五、进阶用法(如更新、写日志)
from tqdm import tqdm
import timepbar = tqdm(total=100)
for i in range(10):time.sleep(0.1)pbar.update(10)
pbar.close()
六、安装
pip install tqdm
在 Jupyter Notebook 中建议使用:
from tqdm.notebook import tqdm
enumerate函数
enumerate
是 Python 的一个内建函数,用于在遍历可迭代对象(如列表、元组等)时,同时获得元素的索引和值。相比使用传统的 range(len(x))
方式,enumerate
更简洁、可读性更强,是写 Pythonic 代码的重要工具。
一、基本语法
enumerate(iterable, start=0)
参数 | 说明 |
---|---|
iterable | 可迭代对象(如列表、字符串、元组、集合、字典等) |
start | 起始索引,默认是 0,也可以设定为任意整数 |
二、基本示例
fruits = ["apple", "banana", "cherry"]for index, fruit in enumerate(fruits):print(index, fruit)
输出:
0 apple
1 banana
2 cherry
三、与传统 range(len(...))
的对比
✅ 推荐写法:
for i, val in enumerate(my_list):...
不推荐写法:
for i in range(len(my_list)):val = my_list[i]...
使用 enumerate
语义更清晰、减少索引出错。
四、start
参数作用
可以自定义索引起始值:
for i, fruit in enumerate(fruits, start=1):print(f"第{i}个水果是 {fruit}")
输出:
第1个水果是 apple
第2个水果是 banana
第3个水果是 cherry
五、常见用法场景
1. 遍历列表时获取索引
names = ["Alice", "Bob", "Charlie"]
for i, name in enumerate(names):print(f"{i}: {name}")
2. 与字典构造器配合使用
d = dict(enumerate(["a", "b", "c"]))
print(d) # {0: 'a', 1: 'b', 2: 'c'}
3. 使用 enumerate
修改可变对象
nums = [1, 2, 3]
for i, num in enumerate(nums):nums[i] = num ** 2
print(nums) # [1, 4, 9]
4. 配合 zip()
遍历多个列表并附带索引
a = ["x", "y", "z"]
b = [10, 20, 30]
for idx, (ai, bi) in enumerate(zip(a, b)):print(f"{idx}: {ai} - {bi}")
六、使用注意事项
问题 | 建议或说明 |
---|---|
只能用于可迭代对象 | 否则抛出 TypeError |
可用于字符串、元组、列表、集合、字典等 | 注意集合和字典遍历顺序是无序的(除非使用 OrderedDict 或 Python 3.7+) |
不能直接修改不可变对象(如字符串) | 修改要借助列表或其它中间变量 |
注意 enumerate 返回的是迭代器 | 想多次使用可以 list(enumerate(...)) |
七、进阶示例
1. 从 enumerate
得到索引和值,并过滤条件
items = ["car", "bike", "train", "plane"]
for i, item in enumerate(items):if "a" in item:print(f"Index {i}: {item}")
2. 解包 enumerate
生成器
e = enumerate(["A", "B", "C"], start=10)
print(list(e)) # [(10, 'A'), (11, 'B'), (12, 'C')]
3. 使用 enumerate
生成 <index, value>
字符串格式
for i, ch in enumerate("abc", 1):print(f"{i}: {ch.upper()}")
输出:
1: A
2: B
3: C
八、与 tqdm 配合使用(进度+索引)
from tqdm import tqdmfor i, data in enumerate(tqdm(dataloader)):# i 是 batch 的编号pass
九、结语
enumerate()
是你写优雅、清晰、高效 Python 循环结构的必备技能,特别适用于:
- 遍历时需要索引信息
- 提高可读性、避免
range(len(...))
出错 - 搭配列表推导或
zip()
使用更灵活