web-dev-qa-db-ja.com

動的に1行に印刷する

文の間に改行を入れずに標準出力を出す文をいくつか作成したいと思います。

具体的に言うと、

for item in range(1,100):
    print item

年です。結果:

1
2
3
4
.
.
.

代わりにこれを取得する方法は次のとおりです。

1 2 3 4 5 ...

さらに良いことに、単一の数字 over /最後の数字を印刷することは可能ですか。したがって、一度に1つの数字だけが画面に表示されますか?

266
Pol

print itemを次のように変更します。

  • Python 2.7のprint item,
  • Python 3のprint(item, end=" ")

データを動的に印刷したい場合は、次の構文を使用してください。

  • Python 3のprint(item, sep=' ', end='', flush=True)
431
ewall

ちなみに......一カ所にmiを印字するように毎回更新する方法は数字を変えるだけです。

一般に、それをする方法は 端末制御コード を使うことです。これは特に単純なケースで、特殊文字は1つだけ必要です。U+ 000D CARRIAGE RETURNは、Python(および他の多くの言語)で'\r'と書かれています。これがあなたのコードに基づく完全な例です。

from sys import stdout
from time import sleep
for i in range(1,20):
    stdout.write("\r%d" % i)
    stdout.flush()
    sleep(1)
stdout.write("\n") # move the cursor to the next line

これに関して驚くべきことがいくつかあります。

  • \rは文字列の先頭にくるので、プログラムの実行中は、カーソルは常に番号の後になります。これは単なる表面的なものではありません。端末エミュレータの中には、逆にすると混乱するものがあります。
  • 最後の行を含めないと、プログラムが終了した後、シェルはそのプロンプトを番号の上に表示します。
  • いくつかのシステムではstdout.flushが必要ですが、そうでなければ何も出力されません。他のシステムはそれを必要としないかもしれませんが、それは害を及ぼしません。

これがうまくいかないことがわかった場合、まず最初に疑うべきことはあなたの端末エミュレータがバグだということです。 vttest プログラムはそれをテストするのに役立ちます。

stdout.writeprintステートメントで置き換えることもできますが、printをファイルオブジェクトの直接使用と混在させないことをお勧めします。

141
zwol

Printステートメントで改行を省略するには、print item,を使用します。

Python 3では、それはprint(item, end=" ")です。

すべての数字を同じ場所に表示したい場合は、例えば(Python 2.7)を使用してください。

to = 20
digits = len(str(to - 1))
delete = "\b" * (digits + 1)
for i in range(to):
    print "{0}{1:{2}}".format(delete, i, digits),

Python 3では、もう少し複雑です。ここではsys.stdoutをフラッシュする必要があります。そうしないと、ループが終了するまで何も表示されません。

import sys
to = 20
digits = len(str(to - 1))
delete = "\b" * (digits)
for i in range(to):
   print("{0}{1:{2}}".format(delete, i, digits), end="")
   sys.stdout.flush()
48
Tim Pietzcker

他の例と同様に、
同様の方法を使用しますが、最後の出力長などを計算するのに時間を費やす代わりに、

私は単純にANSIコードエスケープを使用して行の先頭に戻り、現在のステータス出力を表示する前にその行全体をクリアします。

import sys

class Printer():
    """Print things to stdout on one line dynamically"""
    def __init__(self,data):
        sys.stdout.write("\r\x1b[K"+data.__str__())
        sys.stdout.flush()

繰り返しループで使用するには、次のように呼び出すだけです。

x = 1
for f in fileList:
    ProcessFile(f)
    output = "File number %d completed." % x
    Printer(output)
    x += 1   

もっと見る

16
Matthew

各反復で改行の代わりにスペースを印刷するために、printステートメントに末尾のコンマを追加することができます。

print item,

あるいは、Python 2.6以降を使用している場合は、新しいprint関数を使用することができます。これにより、印刷される各項目の末尾にスペースがあってもいけないように指定できます。欲しいです):

from __future__ import print_function
...
print(item, end="")

最後に、ファイルのようなオブジェクトを返すsysモジュールからインポートすることで、標準出力に直接書き込むことができます。

from sys import stdout
...
stdout.write( str(item) )
14
Eli Courtwright

変化する

print item

print "\033[K", item, "\r",
sys.stdout.flush()
  • "\ 033 [K"は行の終わりまでクリアします
  • \ rは行の先頭に戻る
  • flushステートメントを使用すると、すぐに表示されるので、リアルタイムの出力が得られます。
10
Brooks

単純な結合でうまくいくはずだと思います。

nl = []
for x in range(1,10):nl.append(str(x))
print ' '.join(nl)
5
xortion

私が2.7で使っているもう一つの答えは私がただ "。"を印刷するところです。ループが実行されるたびに(物事がまだ実行されていることをユーザーに示すために)これは次のようになります。

print "\b.",

「。」を印刷します。それぞれの間にスペースのない文字。それはもう少し良く見えてそしてかなりうまく働きます。\bは疑問に思う人のためのバックスペース文字です。

4
copeland3300

「ちなみに......毎回更新する方法なので、miを一箇所に印刷するだけで番号を変更できます。」

それは本当に難しい話題です。これを実現するための1つの方法は、 zack が推奨するもの(コンソール制御コードの出力)です。

あなたは(n)の呪いを使うことができますが、それは主に* nixに働きます。

めったに言及されていない(なぜか理解できない)Windowsでは(そしてここでおもしろい部分になります)、WinAPIへのPythonバインディングを使用できます( http://sourceforge.net/projects/pywin32/ ActivePythonでもデフォルトで使用可能) )それほど難しいことではなく、うまく機能しています。これはちょっとした例です:

import win32console, time

output_handle = win32console.GetStdHandle(  win32console.STD_OUTPUT_HANDLE )
info = output_handle.GetConsoleScreenBufferInfo()
pos = info["CursorPosition"]

for i in "\\|/-\\|/-":
    output_handle.WriteConsoleOutputCharacter( i, pos )
    time.sleep( 1 )

あるいは、print(ステートメントまたは関数、違いはありません)を使用したい場合は、

import win32console, time

output_handle = win32console.GetStdHandle(  win32console.STD_OUTPUT_HANDLE )
info = output_handle.GetConsoleScreenBufferInfo()
pos = info["CursorPosition"]

for i in "\\|/-\\|/-":
    print i
    output_handle.SetConsoleCursorPosition( pos )
    time.sleep( 1 )

win32consoleモジュールを使えば、Windowsコンソールでもっとおもしろいことができます...私はWinAPIの大ファンではありませんが、最近の反感の少なくとも半分はC言語でのWinAPIコードの記述が原因であることに気付きました - Pythonicバインディングはるかに使いやすいです。

他のすべての答えはもちろんすばらしいものですが、... previous 行に印刷したい場合はどうすればよいですか?それとも、それをクリアして同じ行をもう一度書くよりも、複数行のテキストを書くのですか?私の解決策はそれを可能にします。

3
cji

python 2.7用

for x in range(0, 3):
    print x,

python 3の場合

for x in range(0, 3):
    print(x, end=" ")
2
Adnan Ghaffar

数字を互いに上書きするには、次のようにします。

for i in range(1,100):
    print "\r",i,

最初の列に番号が印刷されている限り、これは機能するはずです。

編集:これは最初の列に印刷されていなくても動作するバージョンです。

prev_digits = -1
for i in range(0,1000):
    print("%s%d" % ("\b"*(prev_digits + 1), i)),
    prev_digits = len(str(i))

私は、このコードはWindows上のPython 2.5、つまりWindowsコンソールでテストされ、正しく動作することに注意してください。他の人によると、結果を見るには標準出力のフラッシュが必要かもしれません。 YMMV.

2
Adam Crossland
In [9]: print?
Type:           builtin_function_or_method
Base Class:     <type 'builtin_function_or_method'>
String Form:    <built-in function print>
Namespace:      Python builtin
Docstring:
    print(value, ..., sep=' ', end='\n', file=sys.stdout)

Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep:  string inserted between values, default a space.
end:  string appended after the last value, default a newline.
1
gtrak
for i in xrange(1,100):
  print i,
1
eruciform

Python 3ではこのようにすることができます:

for item in range(1,10):
    print(item, end =" ")

出力:

1 2 3 4 5 6 7 8 9 

タプル: /タプルでも同じことができます:

tup = (1,2,3,4,5)

for n in tup:
    print(n, end = " - ")

出力:

1 - 2 - 3 - 4 - 5 - 

もう一つの例:

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]
for item in list_of_tuples:
    print(item)

出力:

(1, 2)
('A', 'B')
(3, 4)
('Cat', 'Dog')

タプルを解凍することもできます。

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]

# Tuple unpacking so that you can deal with elements inside of the Tuple individually
for (item1, item2) in list_of_tuples:
    print(item1, item2)   

出力:

1 2
A B
3 4
Cat Dog

他のバリエーション:

list_of_tuples = [(1,2),('A','B'), (3,4), ('Cat', 'Dog')]
for (item1, item2) in list_of_tuples:
    print(item1)
    print(item2)
    print('\n')

出力:

1
2


A
B


3
4


Cat
Dog
0
Stryker

これを達成するための最良の方法は\r文字を使用することです。

以下のコードを試してください。

import time
for n in range(500):
  print(n, end='\r')
  time.sleep(0.01)
print()  # start new line so most recently printed number stays
0
vitiral

非常に多くの複雑な答え。 python 3がある場合は、印刷の先頭に\rを配置し、それにend='', flush=Trueを追加します。

import time

for i in range(10):
    print(f'\r{i} foo bar', end='', flush=True)
    time.sleep(0.5)

これは、0 foo bar、次に1 foo barなどをその場で書き込みます。

0
Hugh Perkins

数字を印刷したいだけなら、ループを避けることができます。

# python 3
import time

startnumber = 1
endnumber = 100

# solution A without a for loop
start_time = time.clock()
m = map(str, range(startnumber, endnumber + 1))
print(' '.join(m))
end_time = time.clock()
timetaken = (end_time - start_time) * 1000
print('took {0}ms\n'.format(timetaken))

# solution B: with a for loop
start_time = time.clock()
for i in range(startnumber, endnumber + 1):
    print(i, end=' ')
end_time = time.clock()
timetaken = (end_time - start_time) * 1000
print('\ntook {0}ms\n'.format(timetaken))

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 85 85 87 87 89 89 91 92 93 94 95 96 97 98 99 100 21.1986929975msかかりました

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 85 85 87 87 89 89 91 92 93 94 95 96 97 98 99 100 491.466823551msかかりました

0
Mahmoud Kassem