Pythonライブラリ tqdm 詳細解説:進捗状況をスマートに可視化!🚀

Python

はじめに:tqdmとは?🤔

Pythonでデータ処理や機械学習、あるいは単に時間のかかるループ処理を実行している時、「今どのくらい進んでいるんだろう?」「あとどれくらいで終わるのかな?」と思ったことはありませんか?⏳ そんな時、進捗状況を分かりやすく表示してくれるのが tqdm ライブラリです。

tqdmはアラビア語の「taqaddum (تقدّم)」に由来し、「進捗」を意味します。また、スペイン語の「te quiero demasiado」(I love you so much)の略語でもあるという、おしゃれな一面も持っています。💖

このライブラリの最大の魅力は、その手軽さ柔軟性です。既存のコードにほんの少し手を加えるだけで、見やすいプログレスバーを追加できます。イテラブル(リスト、rangeなど)を `tqdm()` でラップするだけで、基本的な進捗表示が実現します。

tqdmを使うメリットは以下の通りです:

  • 視覚的なフィードバック: 処理の完了度、経過時間、残り時間の予測などを視覚的に把握できます。これにより、処理が止まっているのではないかという不安を解消できます。
  • 簡単な導入: 既存のループ構造を大きく変更することなく、数行のコードで導入可能です。
  • 高いカスタマイズ性: プログレスバーの外観や表示情報を細かく設定できます。
  • 幅広い互換性: Linux, Windows, macOSなど、様々なプラットフォームのコンソールやGUI環境、そしてJupyter Notebook/Labのようなインタラクティブ環境でも動作します。
  • 軽量性: 非常に低いオーバーヘッド(1イテレーションあたり約60ナノ秒)で動作するため、処理速度への影響はほとんどありません。賢いアルゴリズムにより、不要な表示更新をスキップします。
  • 依存関係なし: Python本体と、基本的な制御文字(キャリッジリターン`\r`、ラインフィード`\n`)をサポートする環境があれば動作します。(`curses`のような追加ライブラリは不要です)

この記事では、tqdmの基本的な使い方から、より高度なカスタマイズ、便利な応用例、注意点まで、幅広く解説していきます。この記事を読めば、あなたのPythonスクリプトの実行状況が手に取るように分かるようになるはずです!✨

インストール方法 💻

tqdmのインストールは非常に簡単です。Pythonのパッケージ管理ツールである`pip`を使ってインストールできます。

pip install tqdm

もし、Jupyter NotebookやJupyterLab環境でよりリッチな表示(ウィジェットベースのプログレスバー)を利用したい場合は、`ipywidgets`もインストールしておくと良いでしょう。(tqdmは自動的に`ipywidgets`を検出し、利用可能な場合はノートブック用の表示に切り替えます)

pip install ipywidgets

conda環境を使用している場合は、condaコマンドでもインストール可能です。

conda install -c conda-forge tqdm

インストールが完了したら、Pythonスクリプトやインタラクティブシェルで`import tqdm`を実行して利用を開始できます。

基本的な使い方:イテラブルをラップするだけ!🔄

tqdmの最も基本的な使い方は、ループで処理したいイテラブルオブジェクト(リスト、タプル、rangeオブジェクトなど)を`tqdm()`関数でラップすることです。

import time
from tqdm import tqdm

# rangeオブジェクトをtqdmでラップ
for i in tqdm(range(100)):
    # 何らかの処理をシミュレート
    time.sleep(0.05)

# リストをtqdmでラップ
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
total = 0
for item in tqdm(my_list):
    total += item
    time.sleep(0.1)

print(f"合計: {total}")

これを実行すると、コンソールに以下のようなプログレスバーが表示されます(表示は環境によって多少異なります)。

100%|█████████████████████████████████████████████████████████████| 100/100 [00:05<00:00, 19.89it/s]
100%|█████████████████████████████████████████████████████████████| 10/10 [00:01<00:00,  9.91it/s]
合計: 55

プログレスバーには以下の情報が表示されます:

  • 進捗率 (%)
  • 進捗状況を示すバー
  • 完了したイテレーション数 / 総イテレーション数
  • 経過時間 [<残り時間]
  • 1秒あたりのイテレーション数 (it/s)

便利なショートカット:`trange()`

`tqdm(range(n))` をより短く書くための便利な関数 `trange()` も用意されています。

from tqdm import trange
import time

for i in trange(50):
    time.sleep(0.02)
# 上記は以下と同じ意味
# from tqdm import tqdm
# for i in tqdm(range(50)):
#     time.sleep(0.02)

with文を使った手動制御

ループの対象が単純なイテラブルでない場合や、ループ内で進捗をより細かく制御したい場合は、`with`文を使って`tqdm`オブジェクトを生成し、手動で`update()`メソッドを呼び出すこともできます。

from tqdm import tqdm
import time

# totalで総ステップ数を指定
with tqdm(total=100) as pbar:
    for i in range(10):
        # 何らかの処理
        time.sleep(0.1)
        # 10ステップ進んだことを通知
        pbar.update(10)

この方法では、`total`引数で全体のステップ数を明示的に指定する必要があります。指定しない場合、パーセンテージや残り時間の計算ができません。`with`文を使うことで、処理終了時に自動的にプログレスバーがクリーンアップ(`close()`メソッドが呼ばれる)されるため便利です。

手動制御は、例えばファイルのダウンロード状況を表示する際など、イテレーション回数が事前に不明確な場合や、1回のループで複数のステップが進む場合に役立ちます。

プログレスバーのカスタマイズ 🎨

tqdmは多くのカスタマイズオプションを提供しており、プログレスバーの見た目や表示情報を自由に変更できます。主なオプションをいくつか紹介します。これらのオプションは`tqdm()`や`trange()`の引数として指定します。

引数名説明デフォルト値
descプログレスバーの前に表示される説明文(接頭辞)。何についての進捗かを示すのに便利です。Nonedesc="ファイル処理中"
total総イテレーション(ステップ)数。イテラブルの長さが`len()`で取得できない場合や、手動制御する場合に指定します。len(iterable) (可能な場合)total=1000
leave処理完了後もプログレスバーを表示したままにするか。Trueで残し、Falseで消去します。ネストされたループなどで内側のバーを消したい場合にFalseを使います。True (position=0の場合), False (それ以外)leave=False
ncolsプログレスバー全体の表示幅(文字数)。指定しない場合は環境の幅を自動検出しようとします。固定幅にしたい場合や、幅を狭めたい場合に使います。0を指定するとバー自体を表示しません。環境の幅 or 10 (フォールバック)ncols=80
minintervalプログレスバーの表示を更新する最小間隔(秒)。頻繁すぎる更新を避けるために使います。0.1mininterval=1.0
minitersプログレスバーの表示を更新する最小イテレーション数。指定した回数イテレーションが進むまで表示を更新しません。CPU負荷を軽減したい場合に有効です。0かつdynamic_miniters=Trueの場合、minintervalに合わせて自動調整されます。None (自動調整)miniters=100
asciiプログレスバーの描画にASCII文字を使用するかどうか。Trueを指定すると" 123456789#"のような文字でバーを描画します。環境によってはユニコード文字がうまく表示されない場合に使います。また、カスタム文字を指定することも可能です (例: ascii=" >=")。False (ユニコード文字を使用)ascii=True, ascii="-#"
unitイテレーションの単位。デフォルトは ‘it’ (iteration) ですが、処理対象に合わせて変更できます。'it'unit="件", unit="B" (バイト)
unit_scale数値(イテレーション数やレート)を自動的にスケール(k, M, Gなど)表示するかどうか。Trueまたは1で有効になります。大きな数値を扱う場合に便利です。Falseunit_scale=True
unit_divisor単位のスケーリングを行う際の除数。unit_scale=Trueのときに意味を持ちます。デフォルトは1000ですが、例えばバイト単位をKiB, MiBで表示したい場合は1024を指定します。1000unit_divisor=1024
bar_formatプログレスバー全体の表示フォーマットをカスタマイズします。Pythonのフォーマット文字列構文を使用し、{l_bar}, {bar}, {r_bar}, {n}, {total}, {percentage}, {elapsed}, {remaining}, {rate}などの変数を使用できます。パフォーマンスに影響する可能性があります。'{l_bar}{bar}{r_bar}' (詳細はdoc参照)bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed_s:.0f}s/{remaining_s:.0f}s]'
initialカウンターの初期値。中断した処理を再開する場合などに使用します。0initial=50
position複数のプログレスバーを同時に表示する場合の表示行オフセット(0から始まる)。指定しない場合は自動的に配置されます。ネストされたループやマルチスレッド/マルチプロセス環境で便利です。None (自動)position=1
postfixプログレスバーの後ろに追加情報を表示します。辞書形式で指定し、動的に更新することも可能です(後述)。Nonepostfix={"loss": 0.5, "acc": 0.9}
dynamic_ncolsターミナルのウィンドウサイズが変更されたときに、プログレスバーの幅(ncols)を動的に調整するかどうか。Falsedynamic_ncols=True
colourプログレスバーの色を指定します。CSS3の色名(例: ‘green’, ‘red’)や16進数カラーコード(例: ‘#ff0000’)が使えます。Nonecolour='cyan'

カスタマイズ例

from tqdm import tqdm, trange
import time
import random

# 説明、単位、色、固定幅を指定
for i in trange(100, desc="処理A", unit="ステップ", colour="green", ncols=100):
    time.sleep(0.03)

# 手動制御でpostfixを使って動的な情報を表示
with tqdm(total=50, desc="処理B", unit="データ", postfix={"loss": 0.0, "acc": 0.0}, bar_format="{l_bar}{bar}|{n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]") as pbar:
    current_loss = 1.0
    current_acc = 0.5
    for i in range(5):
        time.sleep(0.5)
        # 情報を更新
        current_loss *= 0.8
        current_acc += 0.05
        pbar.update(10)
        # postfixの内容を更新
        pbar.set_postfix(loss=f"{current_loss:.2f}", acc=f"{current_acc:.2f}")

# ASCII文字で表示、完了後も表示を残す (leave=Trueはデフォルトだが明示)
my_files = [f"file_{j}.dat" for j in range(8)]
for filename in tqdm(my_files, desc="ファイル検証", ascii=True, leave=True):
    time.sleep(0.2)

これらのオプションを組み合わせることで、状況に応じて最適なプログレスバー表示を実現できます。

動的な説明文 (Dynamic Descriptions)

ループの途中で説明文を変更したい場合、`set_description()` メソッドを使用します。

from tqdm import tqdm
import time

items = ["apple", "banana", "cherry", "date", "elderberry"]
pbar = tqdm(items)
for item in pbar:
    # 現在処理中のアイテムを説明文に設定
    pbar.set_description(f"Processing {item}")
    # set_description_str()を使うと末尾の ': ' が付かない
    # pbar.set_description_str(f"Now processing: {item}")
    time.sleep(0.5)

動的な追加情報 (Dynamic Postfix)

ループ中に計算される値(例: 機械学習の損失や精度)などをプログレスバーの末尾に表示したい場合は、`set_postfix()` メソッドを使用します。`postfix`引数で初期値を設定し、ループ内でこのメソッドを呼び出して更新します。

from tqdm import trange
import time
import random

pbar = trange(10, desc="Training", postfix={"loss": "N/A"})
for i in pbar:
    time.sleep(0.3)
    loss = random.random() * (10 - i) / 10
    # postfixの内容を更新
    pbar.set_postfix(loss=f"{loss:.4f}")

`set_postfix_str()` を使うと、整形済みの文字列を直接渡すこともできます。

応用的な使い方 🚀

ネストされたループ (Nested Loops)

ループが入れ子になっている場合でも、tqdmはうまく機能します。内側のループと外側のループそれぞれにプログレスバーを表示できます。`position`引数を使って表示位置を調整すると、より見やすくなります。

from tqdm import trange
import time

for i in trange(3, desc='Outer Loop', position=0, leave=True):
    # 内側のループでは leave=False を指定して、完了後に消すことが多い
    for j in trange(100, desc=f'Inner Loop {i}', position=1, leave=False):
        time.sleep(0.01)

Jupyter Notebook環境では、`tqdm.notebook` モジュールを使うと、ネストされたバーがよりきれいに表示されます(後述)。

Pandasとの連携 🐼

Pandas DataFrameの`apply`や`map`メソッドは非常に便利ですが、データ量が多いと時間がかかることがあります。tqdmはPandasと簡単に連携でき、これらの操作に進捗バーを追加できます。

まず、`tqdm.pandas()`を呼び出してPandas連携機能を有効にします。このとき、`desc`などのtqdmのオプションを渡すことができます。

import pandas as pd
import numpy as np
from tqdm import tqdm
import time

# tqdmのPandas連携を有効化 (オプションも指定可能)
tqdm.pandas(desc="Pandas Apply Progress", colour='magenta')

# サンプルDataFrameを作成
df = pd.DataFrame(np.random.randint(0, 100, (10000, 4)), columns=list('ABCD'))

# 時間のかかる処理をシミュレートする関数
def complex_calculation(row):
    time.sleep(0.0005)
    return row.sum() ** 2

# applyの代わりにprogress_applyを使用
df['E'] = df.progress_apply(complex_calculation, axis=1)

# mapの代わりにprogress_mapを使用 (Seriesに対して)
df['A_str'] = df['A'].progress_map(lambda x: f"Value_{x}")

print(df.head())

`tqdm.pandas()`を実行すると、DataFrameやSeriesオブジェクトに`progress_apply()`と`progress_map()`メソッドが追加されます。これらを使うだけで、`apply`や`map`の処理状況がプログレスバーで表示されるようになります。大規模なデータフレームに対する処理の進捗確認に非常に役立ちます。

非同期処理 (AsyncIO) との連携 ⚡

Pythonの`asyncio`を用いた非同期処理でもtqdmを利用できます。`tqdm.asyncio`モジュールには、非同期イテラブルに対応した`tqdm`クラスや`trange`関数、`gather`や`as_completed`といった非同期タスク管理用の便利なラッパーが用意されています。

import asyncio
from tqdm.asyncio import tqdm, trange
import time

async def my_async_task(i):
    await asyncio.sleep(random.uniform(0.1, 0.5))
    return f"Task {i} finished"

async def main_gather():
    tasks = [my_async_task(i) for i in range(10)]
    # asyncio.gather を tqdm.asyncio.gather でラップ
    results = await tqdm.gather(*tasks, desc="Async Gather")
    # print(results)

async def main_as_completed():
    tasks = [my_async_task(i) for i in range(10)]
    results = []
    # asyncio.as_completed を tqdm.asyncio.tqdm でラップ (totalが必要)
    for future in tqdm(asyncio.as_completed(tasks), total=len(tasks), desc="Async As Completed"):
        result = await future
        results.append(result)
    # print(results)

async def main_async_for():
    # 非同期イテレータ用のtrange
    async for i in trange(5, desc="Async For"):
         await asyncio.sleep(0.2)

# Jupyter Notebookなどイベントループが既にある環境では await main_xxx() を直接実行
# 通常のスクリプトでは asyncio.run() を使う
if __name__ == "__main__":
    import random
    # asyncio.run(main_gather())
    # asyncio.run(main_as_completed())
    asyncio.run(main_async_for())

`tqdm.asyncio.gather`や`tqdm.asyncio.tqdm(asyncio.as_completed(…))`を使うことで、複数の非同期タスクの完了状況をまとめてプログレスバーで表示できます。非同期のWebリクエストやI/Oバウンドな処理の進捗監視に便利です。

注意: `async for` 自体は処理を並行実行するものではありません。イベントループに制御を譲る機会を与える非同期版の`for`ループです。

並行処理 (concurrent.futures) との連携 🤝

マルチスレッディングやマルチプロセッシングを行う `concurrent.futures` とも組み合わせることができます。`as_completed` と組み合わせるのが一般的です。

from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm
import time
import random

def worker_task(i):
    """時間のかかるタスクをシミュレート"""
    sleep_time = random.uniform(0.1, 1.0)
    time.sleep(sleep_time)
    return f"Task {i} completed in {sleep_time:.2f} seconds"

tasks_to_run = list(range(20))

results = []
# ThreadPoolExecutorを使用
with ThreadPoolExecutor(max_workers=5) as executor:
    # タスクをサブミット
    futures = {executor.submit(worker_task, i): i for i in tasks_to_run}

    # tqdmで進捗を表示しながら結果を取得
    # as_completedは完了順にFutureを返すイテレータ
    for future in tqdm(as_completed(futures), total=len(tasks_to_run), desc="Concurrent Tasks"):
        try:
            result = future.result()
            results.append(result)
        except Exception as e:
            print(f"Task generated an exception: {e}")

# print("\nResults:")
# for r in results:
#     print(r)

この例では、`ThreadPoolExecutor`を使って複数のタスクを並行実行し、`as_completed`で完了したものから順次結果を取得しています。`tqdm`で`as_completed`のイテレータをラップすることで、全タスクのうちどれだけが完了したかを進捗バーで表示できます。`ProcessPoolExecutor`を使う場合も同様です。

Jupyter Notebook/Lab 環境での利用 📓

Jupyter環境(NotebookやLab)では、標準の`tqdm`の代わりに`tqdm.notebook`モジュールを使うと、よりリッチなHTMLベースのプログレスバーが表示されます。多くの場合、`ipywidgets`ライブラリが必要になります。

from tqdm.notebook import tqdm, trange
import time

# tqdm.notebook.tqdm を使う
for i in tqdm(range(100), desc="Notebook Progress"):
    time.sleep(0.02)

# trangeもnotebook版がある
for j in trange(50, desc="Notebook trange"):
    time.sleep(0.03)

`tqdm.notebook`版のプログレスバーは、通常のテキストベースのものよりも見た目が良く、色分け(通常: 青、完了: 緑、中断/エラー: 赤)もされるため、状態が把握しやすくなります。

コードをコンソールとJupyterの両方で動かす可能性がある場合は、`tqdm.auto` モジュールを使うと便利です。これは実行環境を自動判別し、適切な`tqdm`(コンソール用かノートブック用か)を選択してくれます。

from tqdm.auto import tqdm, trange # 環境に応じて自動選択
import time

for i in trange(80, desc="Auto Progress"):
    time.sleep(0.025)

コマンドラインツールとしての利用 💻

tqdmはPythonライブラリとしてだけでなく、コマンドラインツールとしても利用できます。パイプ(`|`)と組み合わせて、標準入力から受け取ったデータを処理しながら進捗を表示するのに便利です。

例えば、カレントディレクトリ以下の全てのPythonファイルの行数を数える場合:

# seq 1000000 | tqdm | wc -l  # 100万行をカウント
find . -name '*.py' -type f -print0 | xargs -0 wc -l | tqdm --total $(find . -name '*.py' -type f | wc -l) --unit files > lines.log

大きなファイルを圧縮する場合:

tar -zcf - large_directory/ | tqdm --bytes --total $(du -sb large_directory/ | cut -f1) > backup.tar.gz

`python -m tqdm` としても実行できます。通常のtqdm引数(`–total`, `–unit`, `–desc`など)も指定可能です。

便利な機能とTips ✨

`tqdm.write()`: プログレスバーを壊さずにメッセージ出力

ループの途中で何かメッセージ(ログやデバッグ情報など)を表示したい場合、通常の`print()`関数を使うとプログレスバーの表示が崩れてしまうことがあります。これは、`print()`が改行を出力し、tqdmが同じ行を更新できなくなるためです。

このような場合は、`tqdm.write()`を使用します。この関数は、現在のプログレスバー表示を一時的に消去し、メッセージを出力した後、プログレスバーを再描画してくれるため、表示が崩れません。

from tqdm import tqdm, trange
import time
import random

for i in trange(10):
    time.sleep(0.3)
    if random.random() < 0.2:
        # print(f"デバッグ情報: i = {i}") # これだと表示が崩れる可能性がある
        tqdm.write(f"デバッグ情報: i = {i}") # これならOK

大量のログを出力したい場合は、標準の`logging`モジュールと連携することも可能です(後述)。

標準出力/標準エラー出力のリダイレクト

`tqdm.write()` はデフォルトで標準エラー出力 (`sys.stderr`) に書き込みます。出力先を変更したい場合は `file` 引数を使用します。

import sys
from tqdm import tqdm, trange
import time

# 標準出力に書き込む
for i in trange(5, file=sys.stdout):
    time.sleep(0.2)
    tqdm.write(f"メッセージ {i}", file=sys.stdout)

# ファイルに書き込む
# with open("progress.log", "w") as f:
#     for i in trange(5, file=f):
#         time.sleep(0.2)
#         tqdm.write(f"ログメッセージ {i}", file=f)

Loggingモジュールとの連携

Python標準の `logging` モジュールを使用している場合、`tqdm` はログ出力を適切に処理できます。`logging` のハンドラが `tqdm.write()` を使うように設定するか、`tqdm` 自身が提供するハンドラを使用します。

import logging
import time
from tqdm import tqdm, trange
from tqdm.contrib.logging import logging_redirect_tqdm

# loggingの設定
logging.basicConfig(level=logging.INFO)

# tqdm と logging を連携させる
with logging_redirect_tqdm():
    for i in trange(5):
        time.sleep(0.5)
        if i == 2:
            logging.info(f"中間ポイント {i} に到達しました。")

# withブロックを抜けると通常のlogging動作に戻る
logging.info("処理が完了しました。")

`logging_redirect_tqdm()` コンテキストマネージャを使うことで、そのブロック内での `logging` 出力が `tqdm.write()` を経由するようになり、プログレスバー表示との衝突を防ぎます。

注意点とベストプラクティス ⚠️

  • パフォーマンスへの影響: tqdmは非常に軽量ですが、イテレーションが極端に速い(マイクロ秒単位)ループで毎回表示を更新しようとすると、わずかながらオーバーヘッドが生じることがあります。このような場合は、`mininterval` や `miniters` を調整して更新頻度を下げると良いでしょう。例えば、`miniters=100` とすれば100イテレーションごとにしか表示が更新されなくなり、オーバーヘッドをさらに削減できます。
  • Jupyter環境での表示問題: Jupyter Notebook/Labでプログレスバーがうまく更新されない、複数表示されてしまうなどの問題が発生することがあります。これは、出力のバッファリングなどが原因であることが多いです。
    • `tqdm.notebook` または `tqdm.auto` を使用する。
    • `ipywidgets` が正しくインストールされ、有効になっているか確認する。
    • 古いJupyter環境や`ipywidgets`のバージョンが問題を引き起こす場合があるため、アップデートを試みる。
    • それでも問題が解決しない場合、`tqdm.write()` を使ったデバッグや、明示的な出力フラッシュ (`flush=True`) を試すことがあります。
  • `print()`との併用: 前述の通り、ループ内で通常の`print()`を使うと表示が崩れる可能性があります。メッセージ出力には`tqdm.write()`を使いましょう。
  • 総イテレーション数が不明な場合: ループを開始する前に総イテレーション数が分からない場合、`total`引数を指定せずに`tqdm`を使うことができます。この場合、プログレスバーのパーセンテージや残り時間は表示されませんが、経過時間とイテレーション数、処理速度は表示されます。これはジェネレータなどを扱う場合に便利です。
    import time
    from tqdm import tqdm
    
    def my_generator():
        i = 0
        while i < 15: # 実際はいつ終わるか分からない場合を想定
            yield i
            i += 1
            time.sleep(0.1)
    
    # totalを指定しない
    for item in tqdm(my_generator(), desc="Unknown Total"):
        # 処理...
        pass
    もし、処理の途中で総数が判明した場合は、`pbar.total = new_total` のように後から設定することも可能です。
  • リソース監視との組み合わせ: `psutil`のようなライブラリと組み合わせることで、メモリ使用量などのシステムリソース情報をプログレスバーに表示することも可能です。`set_postfix()`などを活用して動的に情報を更新します。これはリソース消費が激しいタスクの監視に役立ちます。

まとめ 🎉

Pythonライブラリ tqdm は、時間のかかる処理の進捗状況を視覚化するための非常に強力で使いやすいツールです。

  • 基本的なループなら、イテラブルを`tqdm()`でラップするだけ。
  • `desc`, `unit`, `ncols`, `colour`などの豊富なオプションで見た目をカスタマイズ。
  • `total`, `update()`, `with`文を使った手動制御も可能。
  • Pandas DataFrameの処理 (`progress_apply`, `progress_map`) や非同期処理 (`tqdm.asyncio`)、並行処理 (`concurrent.futures`) ともスムーズに連携。
  • Jupyter環境では`tqdm.notebook`や`tqdm.auto`でリッチな表示。
  • `tqdm.write()`でプログレスバーを壊さずにメッセージ出力。
  • コマンドラインツールとしても利用可能。

わずかな手間で、スクリプトの実行状況が格段に分かりやすくなり、開発効率やユーザー体験の向上に繋がります。特にデータ分析、機械学習、バッチ処理など、待ち時間が長くなりがちな作業では必須とも言えるライブラリです。

ぜひ、あなたのPythonプロジェクトにtqdmを導入して、快適な進捗監視を実現してみてください!😊

コメント

タイトルとURLをコピーしました