新しい行ではなく同じ行に印刷しますか?


89

基本的に私はこの男がしたことの反対をしたいです...へへ。

Pythonスクリプト:既存の行を更新するのではなく、シェルに毎回新しい行を出力します

私はそれがどれだけ進んでいるかを教えてくれるプログラムを持っています。

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete"

したがって、len(some_list)が50の場合、最後の行が50回印刷されます。1行印刷して、その行を更新し続けたい。私はこれがおそらくあなたが一日中読むであろう最も怠惰な質問であることを知っています。私は答えを得るためにグーグルに入れる必要がある4つの単語を理解することができません。

更新!私は正しいと思われるmvdsの提案を試しました。新しいコード

print percent_complete,"           \r",

完了率は単なる文字列です(初めて抽象化したので、文字通りにしようとしています)。その結果、プログラムが実行され、プログラムが終了するまで何も出力されず、1行だけに「100%完了」と出力されます。

キャリッジリターンがない場合(ただし、コンマを使用すると、mvdsの提案の半分)、最後まで何も出力されません。そして、印刷します:

0 percent complete     2 percent complete     3 percent complete     4 percent complete    

等々。したがって、新しい問題は、カンマを使用すると、プログラムが終了するまで印刷されないということです。

キャリッジリターンがあり、カンマがない場合は、どちらの場合とまったく同じように動作します。


sys.stdout.isatty()ターミナルで実行していないときにこれらのものを吐き出さないように、チェックすることもできます。
mvds 2010

私はこれを端末から実行しています...しかし良い考えです。いつか必要になると思います。
chriscauley 2010

1
背景は、ところで、いくつかの言語では、\ n(現在は省略)がstdoutにフラッシュする暗黙のシグナルとして機能することです。そうでなければ、多くの人が混乱するでしょう。
mvds 2010

回答:


86

キャリッジリターン、または \r

使用する

print i/len(some_list)*100," percent complete         \r",

カンマは、印刷が改行を追加するのを防ぎます。(そしてスペースは前の出力からラインをクリアに保ちます)

また、print ""少なくとも最終的な改行を取得するには、で終了することを忘れないでください!


12
常に同じ量のデータ(または以前の印刷よりも多い)を行に印刷していることを確認してください。そうしないと、最後にがらくたになってしまいます。
ニコラスナイト

とても近い...私はこれの結果で質問を更新します。
chriscauley 2010

2
@dustynachos:ええ、そのしわを忘れました。Python出力バッファリングの質問を参照してください:stackoverflow.com/questions/107705/python-output-buffering
Nicholas Knight

1
@dustynachos :(または、各印刷呼び出しの後にsys.stdout.flush()を使用します。プログラムの残りの部分の出力バッファリングを気にしない場合は、実際にはより良い場合があります)
Nicholas Knight

2
これは私にはうまくいきません。私は実際にこれを何度も試しましたが、うまくいきませんでした。Macでiter2を使用していますが、ほとんどの場合LinuxサーバーにSSH接続しています。私は実際に機能するこれを行う方法を見つけたことがありません。
bgenchel 2018

33

Python 3.xから、次のことができます。

print('bla bla', end='')

(これfrom __future__ import print_functionは、スクリプト/モジュールの先頭に配置することで、Python 2.6または2.7でも使用できます)

Pythonコンソールのプログレスバーの例:

import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    n=0
    while n<total:
        done = '#'*(n+1)
        todo = '-'*(total-n-1)
        s = '<{0}>'.format(done+todo)
        if not todo:
            s+='\n'        
        if n>0:
            s = '\r'+s
        print(s, end='')
        yield n
        n+=1

# example for use of status generator
for i in range_with_status(10):
    time.sleep(0.1)

\ rも新しい行を追加しているようです
fccoelho 2013年

3
これは改行を取り除きますが、上書きを許可しません。これは著者が望んでいることだと思います。
bgenchel 2018

1
@bgenchelを「\ r」とともに使用すると(コードサンプルのように)、OPが望んでいることを正確に実行します
MiloWielondek20年

33

私にとって、うまくいったのは、レミとシリウスの答えの組み合わせでした。

from __future__ import print_function
import sys

print(str, end='\r')
sys.stdout.flush()

時代遅れ..Python3.8.5の時点で、私だけが機能します:print( "some string"、end = '\ r')
rroger

23

Python 3.3以降では、は必要ありませんsys.stdout.flush()print(string, end='', flush=True)動作します。

そう

print('foo', end='')
print('\rbar', end='', flush=True)

'foo'を 'bar'で上書きします。


2
印刷されたテキストが"\r"。で終わる場合は機能します。
BLI

13

コンソールの場合、おそらく必要になります

sys.stdout.flush()

強制的に更新します。,印刷で使用すると、stdoutのフラッシュがブロックされ、どういうわけか更新されないと思います


print( "..."、end = '\ r')を使用している場合、printステートメントの直後にこのコマンドを実行しない限り、ターミネーターは30秒ごとに行を更新するだけでした。ありがとう
ブライスギンタ2016

4

ゲームの後半ですが、どの答えもうまくいきませんでした(すべてを試したわけではありません)ので、検索でこの答えに何度も出くわしました... python 3では、このソリューションはかなりエレガントですそして、著者が探していることを正確に実行すると信じています。同じ行の1つのステートメントを更新します。行が伸びるのではなく縮む場合は、何か特別なことをしなければならない場合があることに注意してください(文字列を固定長にし、最後にスペースを埋めるなど)

if __name__ == '__main__':
    for i in range(100):
        print("", end=f"\rPercentComplete: {i} %")
        time.sleep(0.2)

1
python => 3.6のためのもっともシンプルでクリーンなオプション
DaveR

3

これは私にとってはうまくいき、それが可能かどうかを確認するために一度ハックしましたが、私のプログラムでは実際には使用されていません(GUIの方がはるかに優れています):

import time
f = '%4i %%'
len_to_clear = len(f)+1
clear = '\x08'* len_to_clear
print 'Progress in percent:'+' '*(len_to_clear),
for i in range(123):
    print clear+f % (i*100//123),
    time.sleep(0.4)
raw_input('\nDone')

2
import time
import sys


def update_pct(w_str):
    w_str = str(w_str)
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(" " * len(w_str))
    sys.stdout.write("\b" * len(w_str))
    sys.stdout.write(w_str)
    sys.stdout.flush()

for pct in range(0, 101):
    update_pct("{n}%".format(n=str(pct)))
    time.sleep(0.1)

\bバック1つのスペースをカーソルの位置を移動します
、我々はすべての方法の行の先頭に戻ってそれを動かすので
、我々は前方にカーソルが移動し、スペースを書いて/右のいずれかで-現在の行をクリアするには、我々 、書き込みスペース
それでは、我々は持っています新しいデータを書き込む前に、カーソルを行の先頭に戻します

Python2.7を使用してWindowscmdでテスト済み


1

このように試してください:

for i in some_list:
    #do a bunch of stuff.
    print i/len(some_list)*100," percent complete",

(末尾にコンマが付いています。)


これは、新しいテキストを古いテキストに追加するだけです(機能的には似ていますが醜いです)。
chriscauley 2010

1

Spyderを使用している場合、行は以前のすべてのソリューションで継続的に印刷されます。これを回避する方法は、次を使用することです。

for i in range(1000):
    print('\r' + str(round(i/len(df)*100,1)) + '% complete', end='')
    sys.stdout.flush()

これは私にとって唯一の実用的なソリューションでした(Python 3.8、Windows、PyCharm)。
z33k

1

Python3以降の場合

for i in range(5):
    print(str(i) + '\r', sep='', end ='', file = sys.stdout , flush = False)

0

これを使用するためのレミの答えに基づいてPython 2.7+

from __future__ import print_function
import time

# status generator
def range_with_status(total):
    """ iterate from 0 to total and show progress in console """
    import sys
    n = 0
    while n < total:
        done = '#' * (n + 1)
        todo = '-' * (total - n - 1)
        s = '<{0}>'.format(done + todo)
        if not todo:
            s += '\n'
        if n > 0:
            s = '\r' + s
        print(s, end='\r')
        sys.stdout.flush()
        yield n
        n += 1


# example for use of status generator
for i in range_with_status(50):
    time.sleep(0.2)

0

ただではなく、のためにPython 3.6+そしてのためにlistint S、だけでなく、あなたのコンソールウィンドウの幅全体を使用して、新しい行にクロスオーバーではない、あなたは以下を使用することができます。

注:この関数get_console_with()はLinuxベースのシステムでのみ機能するため、Windowsで機能するように書き直す必要があることに注意してください。

import os
import time

def get_console_width():
    """Returns the width of console.

    NOTE: The below implementation works only on Linux-based operating systems.
    If you wish to use it on another OS, please make sure to modify it appropriately.
    """
    return int(os.popen('stty size', 'r').read().split()[1])


def range_with_progress(list_of_elements):
    """Iterate through list with a progress bar shown in console."""

    # Get the total number of elements of the given list.
    total = len(list_of_elements)
    # Get the width of currently used console. Subtract 2 from the value for the
    # edge characters "[" and "]"
    max_width = get_console_width() - 2
    # Start iterating over the list.
    for index, element in enumerate(list_of_elements):
        # Compute how many characters should be printed as "done". It is simply
        # a percentage of work done multiplied by the width of the console. That
        # is: if we're on element 50 out of 100, that means we're 50% done, or
        # 0.5, and we should mark half of the entire console as "done".
        done = int(index / total * max_width)
        # Whatever is left, should be printed as "unfinished"
        remaining = max_width - done
        # Print to the console.
        print(f'[{done * "#"}{remaining * "."}]', end='\r')
        # yield the element to work with it
        yield element
    # Finally, print the full line. If you wish, you can also print whitespace
    # so that the progress bar disappears once you are done. In that case do not
    # forget to add the "end" parameter to print function.
    print(f'[{max_width * "#"}]')


if __name__ == '__main__':
    list_of_elements = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
    for e in range_with_progress(list_of_elements):
        time.sleep(0.2)


0

Python 3を使用している場合、これはあなたのためであり、実際に機能します。

print(value , sep='',end ='', file = sys.stdout , flush = False)

0

カウントダウンを表示するために自分でこれを理解しただけですが、パーセンテージでも機能します。

import time
#Number of seconds to wait
i=15
#Until seconds has reached zero
while i > -1:
    #Ensure string overwrites the previous line by adding spaces at end
    print("\r{} seconds left.   ".format(i),end='')
        time.sleep(1)
        i-=1
    print("") #Adds newline after it's done

'/ r'の後に続くものが前の文字列と同じ長さまたはそれより長い(スペースを含む)限り、同じ行で上書きされます。end = ''を含めるようにしてください。そうしないと、改行に出力されます。お役に立てば幸いです。


0

StartRunning()、StopRunning()、boolean getIsRunning()、および0〜100の範囲の値を返す整数getProgress100()を提供するオブジェクト「pega」の場合、これにより、実行中にテキストプログレスバーが提供されます。

now = time.time()
timeout = now + 30.0
last_progress = -1

pega.StartRunning()

while now < timeout and pega.getIsRunning():
    time.sleep(0.5)
    now = time.time()

    progress = pega.getTubProgress100()
    if progress != last_progress:
        print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", end='', flush=True)
        last_progress = progress

pega.StopRunning()

progress = pega.getTubProgress100()
print('\r'+'='*progress+'-'*(100-progress)+' ' + str(progress) + "% ", flush=True)

0

2020年の終わりとLinuxコンソールのPython3.8.5の時点では、これだけが機能します。

print('some string', end='\r')

クレジットはに行きます:この投稿

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.