Python:如何在嵌套循环中用下一个进度条替换tqdm进度条?

9
我在Jupyter Notebook中使用tqdm模块。假设我有以下带有嵌套for循环的代码段。
import time
from tqdm.notebook import tqdm

for i in tqdm(range(3)):
    for j in tqdm(range(5)):
        time.sleep(1)

输出的结果如下:
100%|██████████| 3/3 [00:15<00:00, 5.07s/it]
100%|██████████| 5/5 [00:10<00:00, 2.02s/it]

100%|██████████| 5/5 [00:05<00:00, 1.01s/it]

100%|██████████| 5/5 [00:05<00:00, 1.01s/it]

有没有选项可以在运行期间仅显示当前的进度条 j?因此,在迭代完成后,最终输出将如下所示?
100%|██████████| 3/3 [00:15<00:00, 5.07s/it]
100%|██████████| 5/5 [00:05<00:00, 1.01s/it]
4个回答

13

在创建进度条时,您可以使用 leave 参数。就像这样:

import time
from tqdm import tqdm

for i in tqdm(range(3)):
    for j in tqdm(range(5), leave=bool(i == 2)):
        time.sleep(1)

这将删除内部进度条并在每次重新创建。因此,如果在这些循环中完成了更多的工作而不仅仅是休眠,则进度条将玩起捉迷藏来。 - Hamza Khurshid
1
解决方案有缺点,但我认为这是实现作者所需的更好的方式(代码越少,错误越少)。 - Anton Pomieshchenko
非常感谢。这正是我正在寻找的! - Jaroslav Bezděk
不幸的是,这对于 Pandas 对象的 progress_apply 方法没有帮助。 - vmg

7
您可以通过在内部循环开始之前每次重置进度条对象来实现此目的。
尝试使用以下代码以获得您想要的结果。
import time
from tqdm.notebook import tqdm

#initializing progress bar objects
outer_loop=tqdm(range(3))
inner_loop=tqdm(range(5))

for i in range(len(outer_loop)):
    inner_loop.refresh()  #force print final state
    inner_loop.reset()  #reuse bar
    outer_loop.update() #update outer tqdm

    for j in range(len(inner_loop)):
        inner_loop.update() #update inner tqdm
        time.sleep(1)

输出:

输出


1
嗨@hamza-khurshid,感谢您的回答。我已经添加了一些内容如下。谢谢和最好的问候 - Alain Michael Janith Schroter

3

感谢 @michael-schroter 提醒我,以及 @jaroslav-bezděk 的原始帖子。

我更喜欢 @anton-pomieshchenko 的答案。不过需要注意的是,内部进度条每次外部更新时都会消失和重新出现,如果这种情况频繁发生且速度很快,可能会给人留下不好的印象。

正确的答案是(假设您不需要重复使用外部进度条,但想要重复使用内部进度条):

from time import sleep
from tqdm.auto import tqdm

with tqdm(range(3)) as outer:
    inner_total = 3
    with tqdm(total=inner_total) as inner:
        for i in outer:
            inner.reset(inner_total)  # reinitialise without clearing
            for j in range(inner_total):
                sleep(1)
                inner.update()
            inner.refresh()  # print last state without clearing

这个解决方案正如我所期望的那样工作,两个进度条都会固定在顶部。同时,日志记录也很好用。谢谢! - undefined

-1
请查看@hamza-khurshid对三个循环的修改后答案。
import time
from tqdm.auto import tqdm

#initializing progress bar objects
outer_loop=tqdm(range(3))
mid_loop=tqdm(range(5))
inner_loop=tqdm(range(7))


for i in range(len(outer_loop)):

    mid_loop.refresh()  #force print final state
    mid_loop.reset()  #reuse bar
    outer_loop.update() #update outer tqdm

    for j in range(len(mid_loop)):
        inner_loop.refresh()  #force print final state
        inner_loop.reset()  #reuse bar
        mid_loop.update()  ##update mid tqdm

        for k in range(len(inner_loop)):
            inner_loop.update() #update inner tqdm
            time.sleep(1)
print(i,j,k)

请查看下面的输出:

enter image description here

这也是关于github问题的答案

谢谢 & 最好的祝福

迈克尔


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接