Pythonで処理結果を表示するとき、「ここは改行したくない」「この部分はリアルタイムで流したい」と思う場面はとても多いです。
本記事では、Pythonのprintで改行を制御する方法を、基本のend引数からjoin、flushを使った応用まで、図解を交えながら丁寧に解説します。
Pythonのprintで改行しない基本
printのデフォルト改行とend引数の役割

Pythonのprint関数は、デフォルトでは出力の最後に改行文字'\n'を自動で追加します。
これにより、複数回printを呼び出すと、出力結果は行ごとに分かれて表示されます。
この挙動をコントロールするために使うのがend引数です。
endは「行の末尾に何を付けるか」を指定する引数で、デフォルト値は'\n'(改行)です。
基本的なシグネチャは次のようになっています。
print(*objects, sep=' ', end='\n', file=None, flush=False)
ここでend引数を変更することで、改行をなくしたり、スペースやカンマなど任意の文字に変えることができます。
デフォルトのprint動作の確認
# デフォルトでは、printの末尾に自動的に改行が入ります
print("こんにちは")
print("Python")
# 実際の出力
# こんにちは
# Python
end引数で改行しない書き方

改行をさせない最も直接的な方法は、end引数を空文字''にすることです。
これにより、printは行末に何も付けずにそのまま出力します。
# 改行なしで文字を続けて表示する例
print("A", end="") # 改行しない
print("B", end="") # さらに続けて出力
print("C") # 最後だけ通常の改行
# 出力結果
# ABC
上の例では、1行目と2行目のprintは改行を挿入していないため、「ABC」1行で出力されます。
3行目でデフォルトのend='\n'が使われているため、そこで改行が入ります。
スペースやカンマ区切りにする書き方

end引数は改行の有無だけでなく、任意の文字列を行末に付けるためにも使えます。
例えば、数値をスペース区切りやカンマ区切りで1行に並べたい場合に便利です。
# endにスペースを指定して、数値をスペース区切りで並べる例
for i in range(1, 6):
print(i, end=" ") # 数値のあとにスペースを付けて改行しない
print() # 最後に改行だけ行う
# 出力結果
# 1 2 3 4 5
このように、end=" "とすることで、ループごとにスペースを挟んで出力できます。
カンマ区切りにしたい場合は、次のように書きます。
# endにカンマ+スペースを指定して、カンマ区切りで並べる例
for i in range(1, 6):
print(i, end=", ")
print() # 最後に改行だけ行う
# 出力結果
# 1, 2, 3, 4, 5,
この方法だと末尾にもカンマが付いてしまう点に注意が必要です。
きれいな形式にしたい場合はjoinを使う方法を後述します。
ループ処理で改行させないprintの使い方

ループ処理では、繰り返しごとに改行せず、1行に並べて出力したいことがよくあります。
典型的なパターンは以下の2つです。
1つ目はendを使う方法です。
# endを使ってループの出力を1行にまとめる例
for i in range(10):
print(i, end=" ") # 改行せずに数値とスペースを出力
print() # ループ終了後に改行
# 出力結果
# 0 1 2 3 4 5 6 7 8 9
2つ目はjoinを使ってあらかじめ1つの文字列にまとめてから1回だけprintする方法です。
これは次の章で詳しく説明しますが、大量の要素を扱う際に有利になることがあります。
joinを使った効率的な文字列連結
複数要素を1行で出力するjoinの基本

str.join()は、リストなどの複数要素を、指定した区切り文字で1つの文字列に結合するメソッドです。
改行を伴わず、1行で出力したいときにとても便利です。
基本形は次のとおりです。
# joinの基本的な使い方
words = ["Python", "で", "print", "を", "学ぶ"]
# ' ' (スペース)を区切りにして結合
sentence = " ".join(words)
print(sentence)
# 出力結果
# Python で print を 学ぶ
区切り文字列の側にjoinを呼び出す点が少し独特ですが、慣れるととても使いやすいです。
forループ+printよりjoinが有利なケース

joinは、次のようなケースでforループ+printよりも有利です。
- 出力する要素が多い場合
- 末尾に余分な区切り文字を付けたくない場合
- ログやCSVなど、フォーマットを厳密に揃えたい場合
まず、forループ+printの例を見てみます。
items = ["apple", "banana", "cherry"]
# for + print でスペース区切り出力
for item in items:
print(item, end=" ")
print() # 改行
# 出力結果
# apple banana cherry
この方法だと、末尾にスペースが1つ余分に付くことになります。
見た目だけならほとんど気になりませんが、フォーマットが厳密な場面では問題になることもあります。
同じことをjoinで書くと、次のようになります。
items = ["apple", "banana", "cherry"]
# joinでスペース区切りの文字列を作成してから1回だけ出力
line = " ".join(items)
print(line)
# 出力結果
# apple banana cherry
余分なスペースが全く入らず、printも1回だけで済むため、大量のデータを扱うプログラムでは効率的です。
数値リストをjoinで出力する際の注意点

joinが扱えるのは文字列のシーケンスだけです。
そのため、数値のリストをそのままjoinに渡すとエラーになります。
numbers = [1, 2, 3, 4, 5]
# これはエラーになる
# print(" ".join(numbers))
# 実際に実行すると TypeError が発生します
実行時には次のようなエラーが出ます。
TypeError: sequence item 0: expected str instance, int found
この問題を避けるには、事前に文字列へ変換する必要があります。
よく使われる方法は、mapやリスト内包表記を使う書き方です。
numbers = [1, 2, 3, 4, 5]
# map を使って数値を文字列に変換してから join
line = " ".join(map(str, numbers))
print(line)
# 出力結果
# 1 2 3 4 5
あるいは、リスト内包表記でも同じことができます。
numbers = [1, 2, 3, 4, 5]
# リスト内包表記で文字列に変換
line = ", ".join([str(n) for n in numbers])
print(line)
# 出力結果
# 1, 2, 3, 4, 5
このように、数値リストにjoinを使うときは必ず文字列に変換してから連結するようにしてください。
flushを使ったリアルタイム出力制御
printと標準出力バッファの仕組み

Pythonのprintは、すぐに画面へ文字が表示されるように見えますが、内部的には標準出力バッファを通して出力しています。
多くの環境では、次のようなタイミングでバッファがフラッシュ(中身が実際に画面へ流れる)されます。
- 改行文字’\n’が出力されたとき
- バッファが十分にたまったとき
- プログラムが終了したとき
この仕組みは通常意識しなくてかまいませんが、リアルタイム性が重要な場面(プログレスバーや進捗表示など)では、バッファにたまったまま画面に出てこないことが問題になります。
そこで利用するのがflush引数です。
flush=Trueで即時出力する方法

print関数にはflush引数があり、これをTrueに設定すると、そのprintの出力直後にバッファを強制的にフラッシュします。
import time
# flush=True を使って1文字ずつ即時に表示する例
for ch in "Hello":
print(ch, end="", flush=True) # 改行せず、即時出力
time.sleep(0.5) # 0.5秒待つ
print() # 最後に改行
# 出力結果(体感)
# H(0.5秒後) e(0.5秒後) l(0.5秒後) l(0.5秒後) o(0.5秒後)
flush=Trueがない場合、環境によっては文字がしばらく表示されず、まとめてドンと出てくることがあります。
進捗表示など、ユーザーに逐次的な変化を見せたいときにはflush=Trueを積極的に使うことをおすすめします。
プログレスバーなどでのflushと改行制御

プログレスバーや進捗状況を表示したい場合、1行を上書きし続けるというテクニックがよく使われます。
このとき重要になるのが、次の2点です。
- 改行しないこと(
endで制御) - 出力を即時に画面へ反映すること(
flush=True)
さらに、'\r'(キャリッジリターン)を使って行の先頭にカーソルを戻すと、同じ位置に上書き表示できます。
import time
total = 20
for i in range(total + 1):
progress = int(50 * i / total) # バーの長さ(0〜50)
bar = "#" * progress + "-" * (50 - progress)
# 行頭に戻って同じ行を上書きする
print(f"\r[{bar}] {i}/{total}", end="", flush=True)
time.sleep(0.1)
print() # ループ終了後に改行
# 出力結果(イメージ)
# ターミナル上で1行のバーがだんだん伸びていく
ここではend=""とflush=Trueを組み合わせることで、リアルタイムに更新される1行のプログレスバーを実現しています。
endとflushを組み合わせた出力パターン

endとflushは組み合わせることで、様々な出力パターンを作ることができます。
代表的な組み合わせを表にまとめます。
| パターン | 設定内容 | 主な用途 |
|---|---|---|
| 通常出力 | end='\n', flush=False | 一般的なログやメッセージ |
| 改行なし即時 | end='', flush=True | 文字を1つずつ流す演出、対話的UI |
| 行更新 | end='', flush=True+文頭'\r' | プログレスバーやカウンタの更新 |
例として、カウンタが増えていく様子を1行で更新表示するコードを示します。
import time
for i in range(1, 6):
# '\r' で行頭に戻り、同じ行を上書きする
print(f"\r現在のカウント: {i}", end="", flush=True)
time.sleep(0.7)
print() # 最後に改行
# 出力結果(イメージ)
# 同じ行の「現在のカウント: X」が 1,2,3,4,5 と上書き更新される
このように、endとflushをうまく組み合わせることで、ターミナル上でもリッチな表現が可能になります。
改行させないprintテクニックの実用例
ユーザー入力プロンプトで改行したくない場合

ユーザーに入力してもらうとき、プロンプトと入力を同じ行に表示したいことが多いです。
その場合、printで改行させると、入力が次の行にずれて読みにくくなってしまいます。
そのため、プロンプト表示ではend=''を使って改行しないようにするのが定番です。
# ユーザー入力のプロンプトで改行しない例
print("名前を入力してください: ", end="") # 改行しない
name = input() # ユーザーは同じ行に入力する
print(f"こんにちは、{name}さん!")
# 実行時の画面イメージ
# 名前を入力してください: 山田太郎
# こんにちは、山田太郎さん!
Python標準のinput関数にもprompt引数がありますが、より柔軟な表現をしたい場合や、複雑なフォーマットを組んでから表示したい場合にはprint(..., end='')が役立ちます。
ログ出力で1行に情報をまとめる方法

ログ出力では、1行に必要な情報をまとめて記録することが一般的です。
日時・ログレベル・メッセージ・ユーザーIDなど、複数の要素をきれいに並べるためにjoinが活躍します。
import datetime
level = "INFO"
message = "ユーザーがログインしました"
user_id = "user123"
timestamp = datetime.datetime.now().isoformat(timespec="seconds")
# 各要素を文字列として1行にまとめる
log_line = " | ".join([timestamp, level, message, f"user_id={user_id}"])
print(log_line)
# 出力結果(例)
# 2025-12-13T10:23:45 | INFO | ユーザーがログインしました | user_id=user123
このように文字列連結はjoinで行い、改行はprintに任せるのが、読みやすくて拡張もしやすいスタイルです。
より細かく制御したい場合は、file引数を使ってファイルに直接書き込むこともできますが、その場合も「1行分を1つの文字列として組み立ててから出力する」という方針は同じです。
進捗表示・カウンタ更新でのprint活用法

処理の進み具合をユーザーに見せたい場合、printを工夫して使うことで、見やすく、かつログが無駄に増えない表示を実現できます。
まずは、単純に1行ずつ増やしていく進捗表示です。
import time
total = 5
for i in range(1, total + 1):
print(f"{i}/{total} 処理中...")
time.sleep(0.5)
print("完了しました。")
# 出力結果(行が増えていく)
# 1/5 処理中...
# 2/5 処理中...
# 3/5 処理中...
# 4/5 処理中...
# 5/5 処理中...
# 完了しました。
ログを残したい場合にはこれで十分ですが、単にユーザーに現在の状態を見せたいだけなら、同じ行を更新したほうが見やすくなります。
その場合は'\r'とflush=Trueを組み合わせます。
import time
total = 5
for i in range(1, total + 1):
# '\r' で行頭に戻り、同じ行を上書き
print(f"\r{i}/{total} 処理中...", end="", flush=True)
time.sleep(0.5)
print("\n完了しました。")
# 出力結果(イメージ)
# 同じ行に「1/5 処理中...」→「2/5 処理中...」→ ... と表示が変わっていく
改行をしないend設定と即時反映させるflush=Trueを組み合わせることで、ターミナルでも十分実用的な進捗表示が可能になります。
まとめ
Pythonのprintで改行を制御するには、まずend引数で改行の有無や区切り文字を指定し、複数要素を1行にまとめたいときはjoinで1つの文字列に連結する方法が有効です。
さらにリアルタイム性が重要な場面ではflush=Trueを活用することで、プログレスバーやカウンタ更新などのインタラクティブな表示が実現できます。
ユーザー入力のプロンプトやログ出力など、シーンごとにこれらのテクニックを組み合わせることで、出力を思い通りにコントロールできるようになります。
