tqdm

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

tqdm - Intelligent Progress Bars

tqdm - 智能进度条

tqdm is the standard tool for monitoring long-running loops in Python. It has negligible overhead (about 60ns per iteration) and works everywhere: in the console, in Jupyter notebooks, and even in GUIs.
tqdm是Python中监控长时间运行循环的标准工具。它的开销微乎其微(每次迭代约60纳秒),且可在所有环境中使用:控制台、Jupyter笔记本甚至GUI界面。

When to Use

使用场景

  • Monitoring long-running loops (simulations, data processing, ML training).
  • Tracking progress of file downloads or I/O operations.
  • Providing visual feedback in command-line tools.
  • Integrating progress tracking into pandas operations (progress_apply).
  • Monitoring parallel tasks in concurrent.futures or multiprocessing.
  • Creating nested progress bars for hierarchical tasks (e.g., epochs and batches).
  • 监控长时间运行的循环(模拟程序、数据处理、机器学习训练)。
  • 跟踪文件下载或I/O操作的进度。
  • 在命令行工具中提供可视化反馈。
  • 将进度跟踪集成到Pandas操作中(progress_apply)。
  • 监控concurrent.futures或multiprocessing中的并行任务。
  • 为分层任务创建嵌套进度条(例如:训练轮次(epochs)和批次(batches))。

Reference Documentation

参考文档

Official docs: https://tqdm.github.io/
GitHub: https://github.com/tqdm/tqdm
Search patterns:
from tqdm import tqdm
,
tqdm.pandas()
,
tqdm.notebook
,
tqdm.contrib
官方文档https://tqdm.github.io/
GitHub仓库https://github.com/tqdm/tqdm
常用搜索模式
from tqdm import tqdm
,
tqdm.pandas()
,
tqdm.notebook
,
tqdm.contrib

Core Principles

核心原则

Iterative Wrapper

迭代器包装器

The simplest way to use tqdm is to wrap any iterable:
for item in tqdm(iterable):
. It automatically calculates the length and estimates the time remaining.
使用tqdm最简单的方式是包装任何可迭代对象:
for item in tqdm(iterable):
。它会自动计算长度并估算剩余时间。

Low Overhead

低开销

tqdm is written to be extremely fast. It uses smart algorithms to limit the number of display updates so it doesn't slow down your actual computation.
tqdm的设计追求极致快速。它采用智能算法限制显示更新次数,避免拖慢实际计算过程。

Integration

生态集成

tqdm has specialized modules for different environments (Jupyter, Keras, Pandas, Slack/Telegram notifications).
tqdm针对不同环境提供了专用模块(Jupyter、Keras、Pandas、Slack/Telegram通知)。

Quick Reference

快速参考

Installation

安装

bash
pip install tqdm
bash
pip install tqdm

Standard Imports

标准导入

python
from tqdm import tqdm
import time
python
from tqdm import tqdm
import time

For Jupyter Notebooks specifically:

针对Jupyter笔记本的专用导入:

from tqdm.notebook import tqdm

from tqdm.notebook import tqdm

undefined
undefined

Basic Pattern - Automatic Loop Tracking

基础模式 - 自动循环跟踪

python
import time
from tqdm import tqdm
python
import time
from tqdm import tqdm

Just wrap the range or list

只需包装range或列表

for i in tqdm(range(1000)): time.sleep(0.01) # Simulate work
undefined
for i in tqdm(range(1000)): time.sleep(0.01) # Simulate work
undefined

Critical Rules

关键规则

✅ DO

✅ 推荐做法

  • Use desc - Add a description to the bar so you know exactly which process is running (
    tqdm(range(10), desc="Processing")
    ).
  • Use leave=False for nested loops - This cleans up the inner bars after they finish, preventing console clutter.
  • Use the notebook version - In Jupyter, use
    from tqdm.notebook import tqdm
    for pretty HTML bars.
  • Set total manually - If your iterator doesn't have a
    __len__
    , provide the
    total
    parameter manually.
  • Integrate with Pandas - Use
    tqdm.pandas()
    to see progress on
    .progress_apply()
    .
  • Close manual bars - If using the manual
    pbar = tqdm(...)
    approach, always use a
    with
    statement or call
    pbar.close()
    .
  • 使用desc参数 - 为进度条添加描述,明确当前运行的进程(
    tqdm(range(10), desc="Processing")
    )。
  • 嵌套循环使用leave=False - 内层进度条完成后自动清理,避免控制台混乱。
  • 使用笔记本专用版本 - 在Jupyter中,使用
    from tqdm.notebook import tqdm
    获取美观的HTML进度条。
  • 手动设置total参数 - 如果迭代器没有
    __len__
    属性,手动提供
    total
    参数。
  • 与Pandas集成 - 使用
    tqdm.pandas()
    .progress_apply()
    中查看进度。
  • 手动创建的进度条需关闭 - 如果使用手动方式
    pbar = tqdm(...)
    ,务必使用
    with
    语句或调用
    pbar.close()

❌ DON'T

❌ 不推荐做法

  • Update too often - Avoid manual updates in tight loops (e.g., millions of updates per second); tqdm handles this automatically if you wrap the iterator.
  • Print to console inside tqdm - Standard
    print()
    will break the bar. Use
    tqdm.write("message")
    instead.
  • Ignore overhead - While low, if your loop body is sub-microsecond, any overhead matters; process in batches instead.
  • Forget ascii=True - If working on old terminals or Windows CMD without Unicode support, use
    ascii=True
    to avoid garbled characters.
  • 过于频繁更新 - 避免在紧凑循环中手动更新(例如:每秒数百万次更新);如果包装迭代器,tqdm会自动处理。
  • 在tqdm内部使用print() - 标准
    print()
    会破坏进度条。请改用
    tqdm.write("message")
  • 忽略开销 - 尽管开销很低,但如果循环体耗时不足微秒,任何开销都会有影响;建议批量处理。
  • 忘记设置ascii=True - 如果在旧终端或无Unicode支持的Windows CMD中使用,设置
    ascii=True
    避免乱码。

Anti-Patterns (NEVER)

反模式(绝对避免)

python
from tqdm import tqdm
import time
python
from tqdm import tqdm
import time

❌ BAD: Mixing print() and tqdm (Corrupts the bar)

❌ 错误:混合使用print()和tqdm(会破坏进度条)

for i in tqdm(range(5)): print(f"Doing step {i}") # Bar jumps to next line time.sleep(0.1)
for i in tqdm(range(5)): print(f"Doing step {i}") # Bar jumps to next line time.sleep(0.1)

✅ GOOD: Use tqdm.write()

✅ 正确:使用tqdm.write()

for i in tqdm(range(5)): tqdm.write(f"Doing step {i}") # Bar stays at the bottom time.sleep(0.1)
for i in tqdm(range(5)): tqdm.write(f"Doing step {i}") # Bar stays at the bottom time.sleep(0.1)

❌ BAD: Manual update without closing (Potential memory leak/UI hang)

❌ 错误:手动更新但不关闭(可能导致内存泄漏/UI卡顿)

pbar = tqdm(total=100) for i in range(100): pbar.update(1)
pbar = tqdm(total=100) for i in range(100): pbar.update(1)

Missing pbar.close()!

缺少pbar.close()!

✅ GOOD: Use context manager

✅ 正确:使用上下文管理器

with tqdm(total=100) as pbar: for i in range(100): pbar.update(1)
with tqdm(total=100) as pbar: for i in range(100): pbar.update(1)

❌ BAD: Wrapping an iterator with no length without 'total'

❌ 错误:包装无长度的迭代器却不设置'total'

tqdm(my_generator) # Shows count but no progress bar/ETA

tqdm(my_generator) # 仅显示计数,无进度条/ETA

undefined
undefined

Advanced Usage and Customization

高级用法与自定义

Descriptions and Statistics

描述与统计信息

python
pbar = tqdm(range(100))
for i in pbar:
    # Update description dynamically
    pbar.set_description(f"Processing Step {i}")
    
    # Add custom stats (e.g., loss in ML)
    pbar.set_postfix(loss=0.5/(i+1), accuracy=i/100)
    time.sleep(0.05)
python
pbar = tqdm(range(100))
for i in pbar:
    # 动态更新描述
    pbar.set_description(f"Processing Step {i}")
    
    # 添加自定义统计信息(例如:机器学习中的损失值)
    pbar.set_postfix(loss=0.5/(i+1), accuracy=i/100)
    time.sleep(0.05)

Manual Control (For Non-Iterative Work)

手动控制(适用于非迭代任务)

python
undefined
python
undefined

Useful for tracking bytes in file I/O or API calls

适用于跟踪文件I/O或API调用的字节数

with tqdm(total=1024, unit='B', unit_scale=True, desc="Downloading") as pbar: # Simulate chunked download for chunk_size in [256, 128, 512, 128]: time.sleep(0.5) pbar.update(chunk_size)
undefined
with tqdm(total=1024, unit='B', unit_scale=True, desc="Downloading") as pbar: # 模拟分块下载 for chunk_size in [256, 128, 512, 128]: time.sleep(0.5) pbar.update(chunk_size)
undefined

Integration with Ecosystems

生态系统集成

Pandas Integration

Pandas集成

python
import pandas as pd
from tqdm import tqdm
python
import pandas as pd
from tqdm import tqdm

Initialize tqdm for pandas

为Pandas初始化tqdm

tqdm.pandas(desc="Cleaning Data")
df = pd.DataFrame({'val': range(10000)})
tqdm.pandas(desc="Cleaning Data")
df = pd.DataFrame({'val': range(10000)})

Use progress_apply instead of apply

使用progress_apply替代apply

result = df['val'].progress_apply(lambda x: x**2)
undefined
result = df['val'].progress_apply(lambda x: x**2)
undefined

Nested Progress Bars

嵌套进度条

python
undefined
python
undefined

Perfect for Epochs vs Batches in deep learning

非常适合深度学习中的训练轮次(Epochs)与批次(Batches)

for epoch in tqdm(range(3), desc="Epochs"): for batch in tqdm(range(10), desc="Batches", leave=False): time.sleep(0.05)
undefined
for epoch in tqdm(range(3), desc="Epochs"): for batch in tqdm(range(10), desc="Batches", leave=False): time.sleep(0.05)
undefined

Parallel Processing (concurrent.futures)

并行处理(concurrent.futures)

python
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm

def work(n):
    time.sleep(0.1)
    return n * 2

data = range(50)
with ThreadPoolExecutor() as executor:
    # Use tqdm to monitor map results
    results = list(tqdm(executor.map(work, data), total=len(data)))
python
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm

def work(n):
    time.sleep(0.1)
    return n * 2

data = range(50)
with ThreadPoolExecutor() as executor:
    # 使用tqdm监控map结果
    results = list(tqdm(executor.map(work, data), total=len(data)))

Practical Workflows

实用工作流

1. Large File Reader with Progress

1. 带进度条的大文件读取器

python
import os

def read_large_file(filepath):
    """Read a file while showing a progress bar based on bytes."""
    file_size = os.path.getsize(filepath)
    with tqdm(total=file_size, unit='B', unit_scale=True, unit_divisor=1024) as pbar:
        with open(filepath, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), b''):
                # Process chunk
                pbar.update(len(chunk))
python
import os

def read_large_file(filepath):
    """Read a file while showing a progress bar based on bytes."""
    file_size = os.path.getsize(filepath)
    with tqdm(total=file_size, unit='B', unit_scale=True, unit_divisor=1024) as pbar:
        with open(filepath, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), b''):
                # Process chunk
                pbar.update(len(chunk))

2. Scientific Simulation Suite

2. 科学模拟套件

python
def run_simulation_suite(configs):
    """Run multiple simulations and log failures."""
    results = []
    with tqdm(configs, desc="Suite") as pbar:
        for config in pbar:
            try:
                res = run_single_sim(config)
                results.append(res)
            except Exception as e:
                tqdm.write(f"Error in config {config}: {e}")
            pbar.set_postfix(success=len(results))
    return results
python
def run_simulation_suite(configs):
    """Run multiple simulations and log failures."""
    results = []
    with tqdm(configs, desc="Suite") as pbar:
        for config in pbar:
            try:
                res = run_single_sim(config)
                results.append(res)
            except Exception as e:
                tqdm.write(f"Error in config {config}: {e}")
            pbar.set_postfix(success=len(results))
    return results

3. Training Loop with Custom Postfix

3. 带自定义后缀的训练循环

python
def train_model(epochs, data_loader):
    pbar = tqdm(range(epochs), desc="Training")
    for epoch in pbar:
        loss = compute_loss() # dummy
        acc = compute_acc()   # dummy
        
        # Update the bar with current metrics
        pbar.set_postfix(loss=f"{loss:.4f}", acc=f"{acc:.2%}")
python
def train_model(epochs, data_loader):
    pbar = tqdm(range(epochs), desc="Training")
    for epoch in pbar:
        loss = compute_loss() # dummy
        acc = compute_acc()   # dummy
        
        # 用当前指标更新进度条
        pbar.set_postfix(loss=f"{loss:.4f}", acc=f"{acc:.2%}")

Performance Optimization

性能优化

The mininterval parameter

mininterval参数

By default, tqdm updates every 0.1 seconds. If your terminal is slow (e.g., over SSH or a legacy GUI), increase
mininterval
to 1.0 or 5.0 to reduce network/I/O traffic.
python
for i in tqdm(range(1000000), mininterval=1.0):
    pass
默认情况下,tqdm每0.1秒更新一次。如果你的终端速度较慢(例如:通过SSH连接或旧版GUI终端),可将
mininterval
增加到1.0或5.0以减少网络/I/O流量。
python
for i in tqdm(range(1000000), mininterval=1.0):
    pass

Disabling tqdm in Production

在生产环境中禁用tqdm

You can globally disable bars (e.g., when running in a CI/CD environment or a non-interactive log) by setting
disable=True
.
python
import os
你可以全局禁用进度条(例如:在CI/CD环境或非交互式日志中运行时),只需设置
disable=True
python
import os

Check for environment variable

检查环境变量

is_ci = os.environ.get('CI') == 'true' for i in tqdm(range(100), disable=is_ci): pass
undefined
is_ci = os.environ.get('CI') == 'true' for i in tqdm(range(100), disable=is_ci): pass
undefined

Common Pitfalls and Solutions

常见问题与解决方案

The "Double Bar" Glitch

“双进度条”故障

In Jupyter, sometimes bars don't close properly, leading to stacks of red/green bars.
python
undefined
在Jupyter中,有时进度条无法正确关闭,导致出现一堆红/绿进度条堆叠的情况。
python
undefined

✅ Solution: Always use a 'with' statement or try-finally

✅ 解决方案:始终使用'with'语句或try-finally

Or clear all instances if stuck:

若卡住,可清除所有实例:

from tqdm import tqdm tqdm._instances.clear()
undefined
from tqdm import tqdm tqdm._instances.clear()
undefined

Unicode Error on Windows

Windows下的Unicode错误

Windows CMD (non-Terminal) often struggles with the smooth progress blocks.
python
undefined
Windows CMD(非Terminal)通常无法正常显示平滑的进度块。
python
undefined

✅ Solution: Use ASCII characters only

✅ 解决方案:仅使用ASCII字符

for i in tqdm(range(100), ascii=True): pass
undefined
for i in tqdm(range(100), ascii=True): pass
undefined

Multiple Bars Alignment

多个进度条对齐问题

If your bars are overlapping or jumping:
python
undefined
如果进度条重叠或跳动:
python
undefined

✅ Solution: Specify the position explicitly

✅ 解决方案:显式指定位置

Useful for manual multi-threading

适用于手动多线程场景

pbar1 = tqdm(total=100, position=0) pbar2 = tqdm(total=100, position=1)

tqdm is a small addition to a script that provides immense psychological relief. It provides the "pulse" of your code, ensuring you are always aware of how your long-running scientific tasks are progressing.
pbar1 = tqdm(total=100, position=0) pbar2 = tqdm(total=100, position=1)

tqdm是脚本中一个小小的添加,却能带来巨大的心理慰藉。它提供了代码的“脉搏”,让你始终清楚自己的长时间科学任务进展如何。