有没有办法在Python中创建双进度条? 我想在彼此内部运行两个循环。对于每个循环,我想要一个进度条。我的程序看起来像:
import time
for i1 in range(5):
for i2 in range(300):
# do something, e.g. sleep
time.sleep(0.01)
# update upper progress bar
# update lower progress bar
中间某处的输出应该看起来像
50%|############################ |ETA: 0:00:02
80%|################################################## |ETA: 0:00:04
现有的非常酷progressbar模块似乎不支持。
答案 0 :(得分:21)
使用nested progress bars feature of tqdm,这是一个极低开销,可自定义的进度条库:
$ pip install -U tqdm
然后:
from tqdm import tqdm
import time
for i1 in tqdm(range(5)):
for i2 in tqdm(range(300)):
# do something, e.g. sleep
time.sleep(0.01)
您也可以使用from tqdm import trange
,然后将tqdm(range(...))
替换为trange(...)
。你也可以得到working in a notebook。
答案 1 :(得分:7)
需要你移动光标位置。我写了一个hacky的东西来做它。
此脚本依赖于progressbar模块假定您处于一个新线以绘制进度条的事实。只需向上移动光标(使用'#34的转义码;向上移动光标1行")和向下移动(仅使用换行符。我也可以使用转义码,但换行更容易,更快),一个人可以保持多个进度条。
import progressbar, time, sys
def up():
# My terminal breaks if we don't flush after the escape-code
sys.stdout.write('\x1b[1A')
sys.stdout.flush()
def down():
# I could use '\x1b[1B' here, but newline is faster and easier
sys.stdout.write('\n')
sys.stdout.flush()
# Total bar is at the bottom. Move down to draw it
down()
total = progressbar.ProgressBar(maxval=50)
total.start()
for i in range(1,51):
# Move back up to prepare for sub-bar
up()
# I make a new sub-bar for every iteration, thinking it could be things
# like "File progress", with total being total file progress.
sub = progressbar.ProgressBar(maxval=50)
sub.start()
for y in range(51):
sub.update(y)
time.sleep(0.005)
sub.finish()
# Update total - The sub-bar printed a newline on finish, so we already
# have focus on it
total.update(i)
total.finish()
这当然有点hacky,但它完成了工作。我希望它很有用。
答案 2 :(得分:2)
使用enlighten:
import time
import enlighten
manager = enlighten.get_manager()
ticks = manager.counter(total=100, desc="Ticks", unit="ticks", color="red")
tocks = manager.counter(total=20, desc="Tocks", unit="tocks", color="blue")
for num in range(100):
time.sleep(0.1) # Simulate work
print("The quick brown fox jumps over the lazy dog. {}".format(num))
ticks.update()
if not num % 5:
tocks.update()
manager.stop()
答案 3 :(得分:2)
游戏有点晚了,但这里有一个只使用 tqdm 的答案
import re
from time import sleep
from tqdm import trange
class DescStr:
def __init__(self):
self._desc = ''
def write(self, instr):
self._desc += re.sub('\n|\x1b.*|\r', '', instr)
def read(self):
ret = self._desc
self._desc = ''
return ret
def flush(self):
pass
rng_a = trange(10)
desc = DescStr()
for x in rng_a:
for y in trange(10, file=desc, desc="Y"):
rng_a.set_description(desc.read())
sleep(0.1)
产生:
Y: 90%|######### | 9/10 [00:00<00:00, 9.55it/s]: 100%|##########| 10/10 [00:10<00:00,
答案 4 :(得分:0)
使用atpbar可以轻松完成。
例如:
import time, random
from atpbar import atpbar
for i in atpbar(range(4), name='outer'):
n = random.randint(1000, 10000)
for j in atpbar(range(n), name='inner {}'.format(i)):
time.sleep(0.0001)
上面的代码嵌套了for
个循环。外循环迭代四次。对于外循环的每次迭代,内循环迭代随机选择的次数。内部循环的进度条在循环完成时向上移动。活动进度条保持在底部。进度条的快照可能看起来像
100.00% :::::::::::::::::::::::::::::::::::::::: | 3287 / 3287 |: inner 0
100.00% :::::::::::::::::::::::::::::::::::::::: | 5850 / 5850 |: inner 1
50.00% :::::::::::::::::::: | 2 / 4 |: outer
34.42% ::::::::::::: | 1559 / 4529 |: inner 2
答案 5 :(得分:0)
我基本上只想添加到@ casper.dcl的答案。在稍微不同的情况下,如果您有两个嵌套的for循环,并且只需要一个进度条,则可以执行以下操作。
from tqdm import tqdm
import time
n = 5
m = 300
with tqdm(total=n * m) as pbar:
for i1 in tqdm(range(n)):
for i2 in tqdm(range(m)):
# do something, e.g. sleep
time.sleep(0.01)
pbar.update(1)
我知道这不是问题所在,但对某些人来说还是有帮助的。
答案 6 :(得分:0)
受this answer的启发,我还尝试了enlighten python库并编写了简单的帮助程序.txt
来包装迭代器(代码顶部),并提供了用法示例(代码底部)以及终端直播。
在Linux和Windows中都是彩色的。
pit