- Python
Python inputの使い方|数値変換と複数入力splitのコード集
Pythonの input() とは、キーボード(標準入力)から1行を読み取り、末尾の改行を除いた「文字列」として返す組み込み関数です。 数値として計算したいときは int() や float() で変換し、1行に複数の値があるときは split() で分けてから変換します。この2つの組み合わせを覚えると、ほとんどの入力は数行で受け取れます。
この記事では、1つの整数・小数・空白区切り・カンマ区切り・N行・2次元の入力を「入力例→コード→結果」の早見表にまとめ、そのまま貼って動くコードを用意しました。さらに、数字以外を入れたときの ValueError、個数が合わないときのアンパックのエラーを実際に起こし、try/except と while による再入力ループ、strip、sys.stdin.readline での高速化、EOFError への備えまで、すべて実行結果つきで解説します。コードは Python 3.11.15 で実行して確かめています(仕様は Python 3.14 の公式ドキュメントで確認しました)。
Python inputの早見表(入力例→コード→結果)
まずは「どんな入力を、どのコードで受け取るか」の一覧です。表の「結果」は、右端の print 相当の値を実際に実行して確かめたものです。
| 受け取りたいもの | 入力例 | コード | 結果 |
|---|---|---|---|
| 文字列1つ | Sato |
s = input() |
'Sato' |
| 整数1つ | 12 |
n = int(input()) |
12 |
| 小数1つ | 3.5 |
x = float(input()) |
3.5 |
| 空白区切りの整数2つ | 3 5 |
a, b = map(int, input().split()) |
a=3, b=5 |
| 空白区切りの整数(個数不定) | 10 20 30 |
nums = list(map(int, input().split())) |
[10, 20, 30] |
| 文字列と整数の混在 | Sato 30 |
name, age = input().split() のあと age = int(age) |
'Sato', 30 |
| 先頭1つと残り | 3 10 20 30 |
a, *rest = map(int, input().split()) |
3, [10, 20, 30] |
| カンマ区切りの整数 | 1, 2, 3 |
vals = [int(v) for v in input().split(",")] |
[1, 2, 3] |
| N行の整数(1行目が行数) | 3 10 20 30 |
n = int(input()) のあと rows = [int(input()) for _ in range(n)] |
[10, 20, 30] |
| 2次元(H行W列の整数) | 2 3 1 2 3 4 5 6 |
h, w = map(int, input().split()) のあと grid = [list(map(int, input().split())) for _ in range(h)] |
[[1, 2, 3], [4, 5, 6]] |
| 2次元(文字のマス目) | 2 #.# .#. |
grid = [list(input()) for _ in range(h)] |
[['#', '.', '#'], ['.', '#', '.']] |
| 行数がわからない入力を全部 | a b c |
lines = sys.stdin.read().splitlines() |
['a', 'b', 'c'] |
| 大量の行を速く読む | 100万行 | input = sys.stdin.readline |
約3倍速(後述の計測) |
つまずきやすい入力と、そのときに起きることも先に並べておきます。
| 入力 | コード | 起きること |
|---|---|---|
abc |
int(input()) |
ValueError: invalid literal for int() with base 10: 'abc' |
3.5 |
int(input()) |
ValueError: invalid literal for int() with base 10: '3.5' |
| 空のままEnter | int(input()) |
ValueError: invalid literal for int() with base 10: '' |
3 5 7 |
a, b = map(int, input().split()) |
ValueError: too many values to unpack (expected 2) |
3 |
a, b = map(int, input().split()) |
ValueError: not enough values to unpack (expected 2, got 1) |
| 入力が尽きた(EOF) | input() |
EOFError: EOF when reading a line |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python inputの使い方|数値変換と複数入力splitのコード集」
inputの基本|戻り値はいつも文字列
input() が返すのは、数字を入力したときも含めて必ず文字列(str)です。 ここを押さえると、あとの変換の話がすべてつながります。
# a1.py
s = input()
print(s, type(s))
print(s + s)
12 と入力して実行した結果です。
12 <class 'str'>
1212
12 + 12 の 24 ではなく、文字列の連結で 1212 になりました。計算に使うなら、型を変換する一手間が必要ということです。
プロンプト(入力をうながす文字)を出す
input("...") のように引数を渡すと、その文字列を表示してから入力を待ちます。公式ドキュメントでは「引数 prompt が存在すれば、それが末尾の改行を除いて標準出力に書き出されます。次に、この関数は入力から 1 行を読み込み、文字列に変換して (末尾の改行を除いて) 返します」と説明されています。
name = input("名前を入力してください: ")
print(f"こんにちは、{name}さん")
| ポイント | 内容 |
|---|---|
| 戻り値の型 | 常に str |
| 末尾の改行 | 取り除かれて返る |
| 前後の空白 | そのまま残る(必要なら strip()) |
| プロンプト | 改行なしで表示される。末尾に : など空白を入れると読みやすい |
| 入力が尽きたとき | EOFError が送出される |
数値に変換する|intとfloat
整数1つを受け取る
# a2.py
n = int(input())
print(n * 2)
入力: 12
出力: 24
int() は前後の空白を自動で無視します。12(前後に空白)と入力しても 24 になりました。全角数字の 12 も 12 として読み取られ、1_000(アンダースコア区切り)も 1000 になります。一方、1,000 のようなカンマ入りは ValueError です。
| 入力文字列 | int() の結果(実行して確認) |
|---|---|
12 |
12 |
12(前後に空白) |
12 |
12(全角) |
12 |
1_000 |
1000 |
1,000 |
ValueError |
3.5 |
ValueError |
abc |
ValueError |
| 空文字 | ValueError |
小数1つを受け取る
# a3.py
x = float(input())
print(x, x * 2)
| 入力 | 出力 |
|---|---|
3.5 |
3.5 7.0 |
1e3 |
1000.0 2000.0 |
nan |
nan nan |
3,5 |
ValueError: could not convert string to float: '3,5' |
float() は 1e3 のような指数表記や nan も受け付けます。 入力を厳しく絞りたい場合は、変換後に範囲チェックを足すと安心です(後述の再入力ループで扱います)。
intとfloatのどちらを使うか
| 受け取る値 | 使う関数 | 補足 |
|---|---|---|
| 個数、回数、年齢、番号 | int() |
小数が来たら ValueError で気づける |
| 長さ、重さ、割合、平均 | float() |
整数の入力 3 も 3.0 として読める |
| 整数でも小数でもよい | float() で受けて必要なら int() に |
int(float("3.0")) は 3 |
番号だが先頭の0を残したい(007 など) |
変換しない(文字列のまま) | int("007") は 7 になる |
1行に複数の値を受け取る|splitとmap
空白区切りを分けるsplit
split() は文字列を区切ってリストにします。引数なしの split() は、連続した空白をまとめて1つの区切りとして扱い、前後の空白も無視します。
# a11.py(抜粋)
print(repr("a b c".split()))
print(repr("a b c".split(" ")))
print(repr("".split()))
print(repr("".split(",")))
print(repr("a,b,,c".split(",")))
print(repr("a b c d".split(maxsplit=1)))
['a', 'b', 'c']
['a', '', 'b', 'c']
[]
['']
['a', 'b', '', 'c']
['a', 'b c d']
空白区切りの入力は、引数なしの split() が扱いやすいことがわかります。split(" ") は空白1つごとに切るため、空白が2つ続くと空文字 '' が混ざります。
| 書き方 | 連続する区切り | 空文字に対する結果 | 向いている入力 |
|---|---|---|---|
split() |
まとめて1つとして扱う | [] |
空白・タブ区切り |
split(" ") |
1つずつ区切る(空文字が混ざる) | [''] |
空白の数に意味があるとき |
split(",") |
1つずつ区切る | [''] |
カンマ区切り |
split(maxsplit=1) |
最初の1回だけ分ける | [] |
「コマンド 残り全部」の形 |
2つの整数を受け取る
# a4.py
a, b = map(int, input().split())
print(a + b)
入力: 3 5
出力: 8
この1行は、内側から順に次の3段階で動いています。
flowchart LR
A["input()<br>'3 5'"] --> B["split()<br>['3', '5']"]
B --> C["map(int, ...)<br>3, 5"]
C --> D["a, b = ...<br>a=3, b=5"]
| 段階 | 式 | 値 |
|---|---|---|
| 1 | input() |
'3 5' |
| 2 | input().split() |
['3', '5'] |
| 3 | map(int, ...) |
3 と 5 を順に取り出せるイテレータ |
| 4 | a, b = ... |
a = 3、b = 5(アンパック代入) |
map(int, リスト) は「リストの各要素に int を当てる」という意味です。変換を忘れて a, b = input().split() のまま足し算をすると、文字列の連結になります。
# a12.py
a, b = input().split()
print(a + b)
print(int(a) + int(b))
入力: 3 5
35
8
個数が決まっていない整数をリストで受け取る
# a5.py
nums = list(map(int, input().split()))
print(nums, sum(nums))
入力: 10 20 30
出力: [10, 20, 30] 60
map() の結果はそのままだと1回しか回せないイテレータなので、何度も使うなら list() でリストにしておくのが定番です。リスト内包表記で書いても同じ結果になります。
nums = [int(v) for v in input().split()]
| 書き方 | 特徴 |
|---|---|
list(map(int, input().split())) |
短く書ける。変換関数を1つ当てるだけのときに向く |
[int(v) for v in input().split()] |
条件(if v)や加工(int(v) - 1)を足しやすい |
空のままEnterを押した場合、split() が [] を返すため、結果は空リスト [] になります(エラーにはなりません)。
文字列と数値が混ざった1行
# a10.py
name, age = input().split()
age = int(age)
print(f"{name}さんは{age}歳")
入力: Sato 30
出力: Satoさんは30歳
型が混ざるときは、まず文字列のまま分けてから、数値にしたい変数だけ変換します。
先頭の1つと残りを分ける
# a13.py
a, *rest = map(int, input().split())
print(a, rest)
入力: 3 10 20 30
出力: 3 [10, 20, 30]
*rest は「残り全部をリストで受け取る」という書き方です。「個数 値 値 値 ...」のように、先頭だけ意味が違う入力で役立ちます。
カンマ区切りを受け取る
# a6.py
vals = [int(v) for v in input().split(",")]
print(vals)
| 入力 | 結果 |
|---|---|
1,2,3 |
[1, 2, 3] |
1, 2, 3(カンマの後に空白) |
[1, 2, 3] |
1,2,(末尾にカンマ) |
ValueError: invalid literal for int() with base 10: '' |
int() が前後の空白を無視するので、1, 2, 3 もそのまま読めます。末尾にカンマがあると空文字が1つ混ざって ValueError になるため、空の要素を読み飛ばす条件を足すと安定します。
# a6b.py
vals = [int(v) for v in input().split(",") if v.strip()]
print(vals)
入力: 1,2,
出力: [1, 2]
文字列のまま受け取る場合は int() が空白を取ってくれないので、[v.strip() for v in input().split(",")] のように自分で strip() を当てます。
複数行の入力を受け取る|N行と2次元
1行目が行数、続けてN行
# a7.py
n = int(input())
rows = [int(input()) for _ in range(n)]
print(rows)
入力:
3
10
20
30
出力: [10, 20, 30]
input() を呼ぶたびに1行ずつ読み進むので、for _ in range(n) で n 回呼べば n 行を受け取れます。_ は「使わない変数」を表す慣習的な名前です。
宣言した行数より入力が少ないと、足りない行を読もうとした時点で EOFError になります(3 のあとに2行だけ与えて確認しました)。
EOFError: EOF when reading a line
2次元(H行W列)の整数
# a8.py
h, w = map(int, input().split())
grid = [list(map(int, input().split())) for _ in range(h)]
print(grid)
print(grid[1][2])
入力:
2 3
1 2 3
4 5 6
出力:
[[1, 2, 3], [4, 5, 6]]
6
「1行をリストにする式」を、行数ぶん内包表記で繰り返すのが2次元入力の型です。grid[行][列] の順で取り出せます(どちらも0始まり)。
2次元の文字(マス目)
# a9.py
h = int(input())
grid = [list(input()) for _ in range(h)]
print(grid)
入力:
2
#.#
.#.
出力: [['#', '.', '#'], ['.', '#', '.']]
list("文字列") は1文字ずつのリストになります。書き換えないのであれば grid = [input() for _ in range(h)] と文字列のまま持っても、grid[0][2] のように同じ形で参照できます。
行数がわからない入力を最後まで読む
行数が先に与えられない場合は、入力の終わり(EOF)まで読む書き方を使います。3通りを実行して、どれも同じ結果になることを確かめました。
# b9.py:全部まとめて読む
import sys
lines = sys.stdin.read().splitlines()
print(lines)
# b6.py:1行ずつ処理する(空行は読み飛ばす)
import sys
total = 0
for line in sys.stdin:
line = line.strip()
if not line:
continue
total += int(line)
print(total)
# b8.py:input() と EOFError で読む
lines = []
while True:
try:
line = input()
except EOFError:
break
lines.append(line)
print(lines)
b9.py / b8.py(入力 a, b, c の3行): ['a', 'b', 'c']
b6.py(入力 10, 20, 空行, 30) : 60
| 書き方 | 向いている場面 |
|---|---|
sys.stdin.read().splitlines() |
全体を一度にリストで持ちたい |
for line in sys.stdin: |
1行ずつ処理して、メモリを節約したい |
input() と except EOFError |
既存の input() のコードをそのまま生かしたい |
行の区切りを気にしないなら、全部読んで空白類でまとめて分ける方法もあります。改行位置が入力例と少しずれていても読めるのが利点です。
# b7.py
import sys
data = sys.stdin.read().split()
n = int(data[0])
nums = list(map(int, data[1:1 + n]))
print(n, nums)
入力:
3
10 20
30
出力: 3 [10, 20, 30]
数字以外が入力されたときのValueErrorを再現する
ここからは、つまずきやすいエラーを実際に起こして、原因と直し方を確認します。
intに数字以外を渡したとき
int(input()) に abc を入力した結果です(ファイルのパスは短く表記しています)。
Traceback (most recent call last):
File "a2.py", line 1, in <module>
n = int(input())
^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'abc'
メッセージ末尾の引用符の中に、変換しようとした文字列がそのまま表示されます。 ここを見ると原因がすぐにわかります。
| 末尾の表示 | 原因 | 直し方 |
|---|---|---|
'abc' |
数字以外が入力された | try/except で受け止めて聞き直す |
'3.5' |
小数を int() に渡した |
float() で受ける |
'' |
空のままEnter、または空行を読んだ | 空なら聞き直す/読み飛ばす |
'3,5' |
区切り文字が想定と違う | split(",") にする |
'3 5' |
split() を付け忘れた |
input().split() にする |
'1,000' |
桁区切りのカンマ | replace(",", "") してから変換 |
個数が合わないときのアンパックエラー
a, b = map(int, input().split()) は、値がちょうど2つのときだけ動きます。
3 5 7(多い)を入力したとき:
Traceback (most recent call last):
File "a4.py", line 1, in <module>
a, b = map(int, input().split())
^^^^
ValueError: too many values to unpack (expected 2)
3(少ない)を入力したとき:
ValueError: not enough values to unpack (expected 2, got 1)
3,5(区切りが違う)を入力したとき:
ValueError: invalid literal for int() with base 10: '3,5'
3つとも例外の型は同じ ValueError です。そのため except ValueError ひとつで、変換の問題と個数の問題をまとめて受け止められます。
| メッセージ | 意味 | 直し方 |
|---|---|---|
too many values to unpack (expected 2) |
左辺の変数より値が多い | 変数を増やす/a, b, *_ = ... で余りを受ける/リストで受ける |
not enough values to unpack (expected 2, got 1) |
左辺の変数より値が少ない | 入力形式を確認/リストで受けて len() で分岐 |
個数が決まっていない入力は、アンパックせずリストで受けるのが素直です。
nums = list(map(int, input().split()))
if len(nums) != 2:
print(f"2つ入力してください({len(nums)}個でした)")
try/exceptとwhileで再入力ループを作る
まずは1回だけ受け止める
# b1.py
try:
n = int(input("整数を入力: "))
print(f"2倍は {n * 2}")
except ValueError:
print("整数として読み取れませんでした")
整数を入力: abc
整数として読み取れませんでした
整数を入力: 7
2倍は 14
正しい値が入るまで聞き直す
while True: で囲み、正しく読めたときだけ break で抜けるのが再入力ループの基本形です。
# b2.py
while True:
text = input("1〜10の整数を入力: ").strip()
try:
n = int(text)
except ValueError:
print(f" '{text}' は整数として読み取れません。もう一度どうぞ")
continue
if 1 <= n <= 10:
break
print(f" {n} は範囲外です。もう一度どうぞ")
print(f"受け取った値: {n}")
abc → 空Enter → 3.5 → 99 → 7 の順に入力した結果です(入力をファイルから流し込んだため、入力した文字そのものは画面に出ていません)。
1〜10の整数を入力: 'abc' は整数として読み取れません。もう一度どうぞ
1〜10の整数を入力: '' は整数として読み取れません。もう一度どうぞ
1〜10の整数を入力: '3.5' は整数として読み取れません。もう一度どうぞ
1〜10の整数を入力: 99 は範囲外です。もう一度どうぞ
1〜10の整数を入力: 受け取った値: 7
流れを図にすると次のとおりです。
flowchart TD
A[入力を受け取る] --> B{int に変換できる?}
B -- いいえ --> C[メッセージを出す] --> A
B -- はい --> D{範囲内?}
D -- いいえ --> E[メッセージを出す] --> A
D -- はい --> F[break でループを抜ける]
複数の値をまとめて聞き直す
変換とアンパックを同じ try に入れると、どちらのエラーも1か所で受け止められます。
# b4.py
while True:
try:
a, b = map(int, input("2つの整数を空白区切りで: ").split())
break
except ValueError as e:
print(f" 読み取れませんでした({e})")
print(a + b)
3 → 3 5 7 → 3 x → 3 5 の順に入力した結果です。
2つの整数を空白区切りで: 読み取れませんでした(not enough values to unpack (expected 2, got 1))
2つの整数を空白区切りで: 読み取れませんでした(too many values to unpack (expected 2))
2つの整数を空白区切りで: 読み取れませんでした(invalid literal for int() with base 10: 'x')
2つの整数を空白区切りで: 8
使い回せる関数にする(回数の上限とEOFつき)
何度も使うなら関数にまとめておくと便利です。範囲チェック、聞き直しの上限、入力が尽きたときの扱いを入れた完成形です。
# b3.py
def ask_int(prompt, lo=None, hi=None, retries=3):
"""整数を受け取る。retries 回まで聞き直し、入力が尽きたら None を返す"""
for _ in range(retries):
try:
text = input(prompt).strip()
except EOFError:
print("\n入力が終わりました")
return None
try:
n = int(text)
except ValueError:
print(f" '{text}' は整数として読み取れません")
continue
if (lo is not None and n < lo) or (hi is not None and n > hi):
print(f" {lo}〜{hi} の範囲で入力してください")
continue
return n
print(" 回数の上限に達しました")
return None
qty = ask_int("数量(1〜99): ", lo=1, hi=99)
print("結果:", qty)
| 入力 | 実行結果(最後の行) |
|---|---|
x → 0 → 12 |
結果: 12 |
x → y → z |
回数の上限に達しました のあと 結果: None |
x のあと入力が尽きる |
入力が終わりました のあと 結果: None |
isdecimalで事前に確かめる方法との比較
「変換の前に文字列を調べる」方法もあります。str のメソッド3つの結果を実行して比べました。
| 入力 | isdecimal() |
isdigit() |
isnumeric() |
int() で変換 |
|---|---|---|---|---|
12 |
True | True | True | できる |
-5 |
False | False | False | できる(-5) |
3.5 |
False | False | False | できない |
12(全角) |
True | True | True | できる |
② |
False | True | True | できない |
十 |
False | False | True | できない |
マイナスの数は3つとも False になり、② や 十 は True なのに int() では変換できません。 「変換できるかどうか」を知りたいなら、実際に int() を呼んで try/except で受け止めるのがいちばん確実です。0以上の整数だけを受け付けたい場合に限れば、isdecimal() が int() の挙動といちばん近くなります。
stripで前後の空白を取り除く
input() は末尾の改行だけを除き、前後の空白はそのまま返します。 文字列を比較するときは strip() を挟むと、空白の有無による食い違いを防げます。
# b11.py
text = input("続けますか? [y/n]: ").strip().lower()
if text in ("y", "yes"):
print("続行します")
elif text in ("n", "no", ""):
print("終了します")
else:
print("y か n で答えてください")
入力「 Y 」 → 続行します
入力(空Enter)→ 終了します
| メソッド | 取り除く場所 | 例(" 12 \n" に対して) |
|---|---|---|
strip() |
前後の空白・改行 | '12' |
rstrip() |
末尾の空白・改行 | ' 12' |
rstrip("\n") |
末尾の改行だけ | ' 12 ' |
lstrip() |
先頭の空白 | '12 \n' |
lower() |
(大文字を小文字に) | Y と y を同じに扱える |
数値に変換する場合は int() や float() が空白を無視するので strip() は省けます。文字列のまま使う・比較するときに strip() が効いてきます。
sys.stdin.readlineで高速に読む
行数が多い入力では、input() の代わりに sys.stdin.readline() を使うと速くなります。
書き方と、inputとの違い
# b5.py
import sys
input = sys.stdin.readline # 以降の input() を置き換える
s = input()
print(repr(s))
n = int(input())
print(n)
name = input().rstrip("\n")
print(repr(name))
last = input()
print(repr(last))
hello、42、Sato Taro(末尾に空白)の3行を与えた結果です。
'hello\n'
42
'Sato Taro '
''
違いは2つあります。
| 項目 | input() |
sys.stdin.readline() |
|---|---|---|
| 末尾の改行 | 取り除かれる | 残る('hello\n') |
| 入力が尽きたとき | EOFError |
空文字 '' を返す(例外にならない) |
| プロンプト | 引数で表示できる | 表示しない(必要なら print(..., end="")) |
| 速度(100万行) | 基準 | 約3倍速(下の計測) |
int() や split() は改行を無視するので、数値を読むぶんには書き換えなくてもそのまま動きます。文字列として使う行だけ rstrip("\n") か strip() を付けると覚えておくと十分です。
100万行で速度を比べる
1〜10億の整数を100万行並べたファイルを用意し、合計を求める3つのプログラムを3回ずつ実行しました(Python 3.11.15、Linuxコンテナ上。数値は環境によって変わります)。
# s1.py:input()
n = int(input())
total = 0
for _ in range(n):
total += int(input())
print(total)
# s2.py:sys.stdin.readline
import sys
input = sys.stdin.readline
n = int(input())
total = 0
for _ in range(n):
total += int(input())
print(total)
# s3.py:全部読んでまとめて分ける
import sys
data = sys.stdin.buffer.read().split()
n = int(data[0])
print(sum(map(int, data[1:n + 1])))
| 方法 | 1回目 | 2回目 | 3回目 |
|---|---|---|---|
input() |
0.82秒 | 0.89秒 | 0.76秒 |
sys.stdin.readline() |
0.29秒 | 0.26秒 | 0.25秒 |
sys.stdin.buffer.read().split() |
0.17秒 | 0.19秒 | 0.15秒 |
readline に置き換えるだけで約3倍、全部まとめて読むと約5倍でした(プロセスの起動時間を含みます)。数百行程度なら差は体感できないので、読みやすい input() のままで問題ありません。
| 行数の目安 | おすすめ |
|---|---|
| 〜数千行、対話的な入力 | input() |
| 数万〜数十万行 | input = sys.stdin.readline |
| 数十万行以上、形式が単純 | sys.stdin.read().split() や sys.stdin.buffer.read().split() |
sys.stdin.buffer.read() はバイト列(bytes)を返します。int() はバイト列の数字もそのまま変換できますが、文字列として扱いたい場合は sys.stdin.read() を使います。
EOFErrorと中断(Ctrl+C)に備える
EOFErrorが起きる場面
EOFError は「読む行がもう残っていない」ときに input() が送出する例外です。何も入力を与えずに int(input()) を実行すると、次のようになりました。
Traceback (most recent call last):
File "a2.py", line 1, in <module>
n = int(input())
^^^^^^^
EOFError: EOF when reading a line
| 場面 | なぜ起きるか | 対処 |
|---|---|---|
| ファイルやパイプから入力を流している | 行数が想定より少ない | 入力ファイルの行数を確認/except EOFError |
| 端末で Ctrl+D(Windowsは Ctrl+Z のあとEnter)を押した | 入力の終わりを送る操作 | except EOFError で終了処理へ |
| オンライン実行環境で入力欄が空 | 標準入力が空 | 入力欄に値を入れる |
| 行数のわからない入力をループで読む | 最後まで読み切った | except EOFError: break(正常な終わり) |
疑似端末の上で実際に Ctrl+D を送ったところ、EOFError(メッセージなし)で終了することも確認しました。
EOFと中断をまとめて受け止める
# 対話プログラムの入口の例
def main():
while True:
try:
text = input("コマンド> ").strip()
except EOFError:
print("\n入力が終わったので終了します")
break
except KeyboardInterrupt:
print("\n中断しました")
break
if text == "quit":
break
print(f"受け取り: {text}")
if __name__ == "__main__":
main()
Ctrl+C を押すと KeyboardInterrupt が送出されます。try/except KeyboardInterrupt で受け止めた最小のコードを疑似端末で実行し、次の表示になることを確かめました(上の main() 全体は入力を流し込む形でのみ確認しています)。
名前: ^C
中断しました
EOFError は「入力の終わり」、KeyboardInterrupt は「利用者による中断」です。どちらも異常ではなく、丁寧に終了メッセージを出して終われば使い心地がよくなります。
入力を渡して手早く試す方法
毎回キーボードから打つ代わりに、入力を流し込むと確認が速くなります。この記事の検証もこの方法で行いました。
# 1行だけ渡す
echo "3 5" | python3 a4.py
# 複数行を渡す
printf '3\n10\n20\n30\n' | python3 a7.py
# ファイルから渡す
python3 a8.py < input.txt
| 方法 | 書き方 | 向いている場面 |
|---|---|---|
| パイプ | echo "3 5" | python3 main.py |
1行の入力をさっと試す |
| printf | printf '3\n10\n' | python3 main.py |
複数行、末尾の改行の有無まで制御したい |
| リダイレクト | python3 main.py < input.txt |
同じ入力で何度も試す |
流し込んだ場合、プロンプトは表示されますが、入力した文字そのものは画面に出ません。出力が1行につながって見えるのはそのためです。
よくあるつまずきと直し方
| 症状 | 原因 | 直す前 | 直した後 |
|---|---|---|---|
3 と 5 を足したら 35 |
文字列のまま連結した | a + b |
int(a) + int(b) |
TypeError: can only concatenate str (not "int") to str |
文字列と数値を + した |
"合計" + n |
f"合計{n}" |
| 空白2つで空文字が混ざる | split(" ") を使った |
input().split(" ") |
input().split() |
y と比べても一致しない |
前後に空白、大文字 | input() == "y" |
input().strip().lower() == "y" |
map の結果を2回使うと空になる |
イテレータは1回きり | m = map(int, ...) |
m = list(map(int, ...)) |
readline に変えたら文字列比較が合わない |
末尾に改行が残る | input() == "end" |
input().strip() == "end" |
| 入力を待ったまま止まって見える | プロンプトがなく、入力待ちに気づかない | input() |
input("値を入力: ") |
チェックリスト
- [ ] 計算に使う値は
int()かfloat()で変換した - [ ] 1行に複数の値があるときは
split()を付けた - [ ] 区切り文字(空白か、カンマか)を入力形式と合わせた
- [ ] 利用者が手で入力する箇所は
try/except ValueErrorとwhileで聞き直せるようにした - [ ] 文字列として比較する値に
strip()を当てた - [ ] 行数が多いときは
sys.stdin.readlineを検討した - [ ] 入力が尽きたとき(
EOFError)の動きを決めた
よくある質問
Q. input() で数値をそのまま受け取ることはできますか?
A. input() の戻り値は常に文字列です。n = int(input()) や x = float(input()) のように、受け取ってすぐ変換するのが定番の書き方です。
Q. map(int, input().split()) と list(map(int, input().split())) はどう使い分けますか?
A. a, b = ... のようにその場でアンパックするなら map のままで足ります。あとで何度も使う、len() や添字で扱う、という場合は list() でリストにします。
Q. 入力が整数か小数かわからないときはどうしますか?
A. float() で受けると、3 も 3.5 も読めます。整数として扱いたいときだけ、x.is_integer() で確かめてから int(x) に変換する方法があります。
Q. EOFError: EOF when reading a line が出ます。どこを見ればよいですか?
A. input() を呼んだ回数に対して、与えた入力の行数が足りていない状態です。入力欄やファイルの行数と、for _ in range(n) の回数が合っているかを確認します。行数が決まっていない入力なら、except EOFError: break で読み終わりとして扱います。
まとめ
input()の戻り値は常に文字列。計算するならint(input())、小数ならfloat(input())- 1行に複数の値は
map(int, input().split())、個数不定ならlist(...)で受ける - N行は
[int(input()) for _ in range(n)]、2次元は[list(map(int, input().split())) for _ in range(h)] - 数字以外や個数の不一致はどちらも
ValueError。try/except ValueErrorとwhile Trueで聞き直せる - 文字列として使う入力には
strip()。数値への変換は空白を自動で無視する - 行数が多いときは
input = sys.stdin.readline(100万行で約3倍速)。末尾の改行が残る点だけ意識する - 入力が尽きると
EOFError。except EOFErrorで終了処理に進める
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Python inputの使い方|数値変換と複数入力splitのコード集」
株式会社RJCでは、Pythonの入力処理のような基礎を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。