Python tqdm завершается перед повторением, когда указано значение total - PullRequest
0 голосов
/ 20 марта 2020

Я искал решение для индикатора выполнения и наткнулся на tqdm. После интеграции его в мою программу и следования примерам, он отлично работал с той итерацией, которую я указал, но изначально не отображал индикатор выполнения. Я обнаружил, что используемая итерация не поддерживает len. Я изменил код так, чтобы параметр total был задан вручную, и теперь при запуске l oop программа завершает работу с прогрессом 0%. Ниже приведены исходный и модифицированный код с выводом:

Исходный код:

import pathlib
from tqdm import tqdm

paths = pathlib.Path('F://Music').rglob('*.mp3')

for f in tqdm(paths):
    # do stuff that takes time
    print(f.name) # prints ok

Начальный вывод: 320it [00:00, 25528.56it/s]

Измененный код:

import pathlib
from tqdm import tqdm

paths = pathlib.Path('F://Music').rglob('*.mp3')

cnt = 0
for p in paths: cnt += 1

for f in tqdm(paths, total=cnt):
    # do stuff that takes time
    print(f.name) # line not reached

Новый вывод: 0%| | 0/320 [00:00<?, ?it/s]

Кажется, что указание total в этом случае нарушает его, даже если общее количество правильное.

1 Ответ

1 голос
/ 20 марта 2020

Ваша переменная paths, определяемая paths = pathlib.Path('F://Music').rglob('*.mp3'), не является структурой данных, подобной списку, а генератором .

Когда вы перебираете ее, чтобы получить ее длину в переменной cnt, вы исчерпали генератор, и когда вы попытались получить данные от него во второй раз (когда вы использовали tqdm), эти данные больше не существовали.

Один из способов преобразовать генератор в список - это выполнить фактическое преобразование, то есть paths_list = list(paths), а затем вызвать tqdm поверх него. Это может быть не лучшим решением, если ваша переменная paths содержит огромное количество данных.


Этот код должен работать нормально:

import pathlib
from tqdm import tqdm

paths = pathlib.Path('F://Music').rglob('*.mp3')
paths_list = list(paths)

for f in tqdm(paths_list):
    print(f.name)
...