小技です。
検索してもそれっぽい感じの記事があまり出なかったので投稿。
前提
リスト内包表記内で時間のかかる処理を行っているとき、進捗状況をprint
したい!
ということが人によってはあると思います。ないかも。
print_in_list_test.py
import time
def heavy_function(num):
time.sleep(1) # めちゃんこ時間かかる処理
return "かたつむりが{num}匹".format(num=num)
def print_in_list_test():
#print() # 進捗状況を出力したいけど、全部やった後かやる前しか出力できない
outputs = [heavy_function(num)
for num in range(1, 10)] # ここでめっちゃ時間かかる…
print("、".join(outputs))
print("処理開始")
print_in_list_test()
print("処理終了")
out
処理開始
かたつむりが1匹、かたつむりが2匹、かたつむりが3匹、かたつむりが4匹、かたつむりが5匹、かたつむりが6匹、かたつむりが7匹、かたつむりが8匹、かたつむりが9匹
処理終了
解決策
あまり綺麗ではないですが、
-
tuple
を一時生成する -
tuple
内でprint
した後に、メインのデータを選択
というようにすることで、リスト内包表記内でのprint
が実現できます。
print_in_list_test2.py
import time
def heavy_function(num):
time.sleep(1) # めちゃんこ時間かかる処理
return "かたつむりが" + str(num) + "匹"
def print_in_list_test2():
outputs = [(print("\r処理中:" + str(num), end=""),
heavy_function(num))[1] # 一時tuple を作成して即廃棄
for num in range(1, 10)]
print() # ↑のprint内で \r を使ってるので行を改める
print("、".join(outputs))
print("処理開始")
print_in_list_test2()
print("処理終了")
out
処理開始
処理中:9
かたつむりが1匹、かたつむりが2匹、かたつむりが3匹、かたつむりが4匹、かたつむりが5匹、かたつむりが6匹、かたつむりが7匹、かたつむりが8匹、かたつむりが9匹
処理終了
追記:カウンター側で出力する
コメントで頂いた情報です。(ありがとうございます!)
関数を用意する必要がありますが、余計な処理が無くて自然です。
ライブラリもあるんだそうな。
GitHub - tqdm_tqdm A Fast, Extensible Progress Bar for Python and CLI.html
print_in_list_test3.py
import time
def heavy_function(num):
time.sleep(1) # めちゃんこ時間かかる処理
return "かたつむりが{num}匹".format(num=num)
def progress(seq):
for num in seq:
print("\r処理中:{num}".format(num=num), end="")
yield num
print() # ↑のprint内で \r を使ってるので行を改める
def print_in_list_test3():
outputs = [heavy_function(num) for num in progress(range(1, 10))]
print("、".join(outputs))
print("処理開始")
print_in_list_test3()
print("処理終了")
感想
べんり!!