HOWTO · Python

Python While ループ ユーザー入力

Python では、input() 関数を while ループ内で使用して、特定の条件が満たされるまでデータを入力できます。

このページの内容

コマンドラインプログラムで、ユーザーが指定した単語やメニュー項目を入力するまで繰り返し尋ねたい場合は、while ループ内で Python の input() を使います。入力は毎回テキストとして読み取り、「続行」か「終了」かを確認してから、有効な値であることを確かめたうえで数値に変換します。

input() 関数を理解する

Python 3 の input() はプロンプトを表示し、ユーザーが Enter キーを押すまで待ってから、入力された行を文字列として返します。数値に見える値でも、返されるのはテキストです。たとえば 12 と入力すると、整数の 12 ではなく文字列 "12" が返ります。後続の処理で数値が必要になったときにだけ、int() または float() で変換します。

簡単な対話型プログラムでは、何を入力すればよいかが伝わるプロンプトを使いましょう。入力した値はテキストとして比較したり、保存したり、変換関数に渡したりできます。input() を1回呼び出すと1行を読み取ります。プログラムが入力を繰り返し集められるのは、その呼び出しをループに入れるためです。まずはループを使わず、1回だけ入力を受け取る例を見てみましょう。

このセクションのコードと表示されるラベルや出力は英語のままです。

from io import StringIO
import sys

sys.stdin = StringIO("Ada\n")
name = input("What is your name? ")
print("Hello,", name)
What is your name? Hello, Ada

この例では、標準入力から Ada を渡すため、キーボード入力を待たずに実行できます。対話型ターミナルで使う場合は、StringIO と sys.stdin の行を省きます。すると input() はユーザーが名前を入力して Enter キーを押すまで待ち、その次の行に挨拶を表示します。

while ループで入力を繰り返す

番兵値とは、ループを終了させる値です。たとえば done が使えます。最初に条件を判定できるよう、ループの前に値を初期化します。ループを1回実行するたびに新しい応答を読み取り、その値を更新します。応答が番兵値と一致すると、次の条件判定でループが終了します。有効なデータと区別できる番兵値を選び、比較方法も一貫させましょう(たとえば DONE でも終了させるなら、大文字と小文字を正規化して比較します)。

次の例を実行してください。

このセクションのコードと表示されるラベルや出力は英語のままです。

responses = iter(["red", "blue", "done"])

def read_response(prompt):
    print(prompt, end="")
    response = next(responses)
    print(response)
    return response

answer = ""
while answer != "done":
    answer = read_response("Enter a color (done to finish): ")
    if answer != "done":
        print("Saved:", answer)
Enter a color (done to finish): red
Saved: red
Enter a color (done to finish): blue
Saved: blue
Enter a color (done to finish): done

この例では、read_response を通じて固定の入力列を渡し、毎回同じやり取りを再現できるようにしています。ターミナルで使うプログラムでは、その呼び出しを input("Enter a color (done to finish): ") に置き換え、番兵値の比較とループの構造はそのまま使います。ループは番兵値を読み取りますが、保存はしません。値を更新しないと条件がいつまでも真のままになることがあるため、続行する各回で必ず新しい応答を取得してください。

入力値を検証する

応答をテキストとして読み取り、変換する前に終了用の番兵値かどうかを確認します。int() を try/except ValueError の中で呼び出し、変換エラーが起きたらループで再入力を促します。この単独で動かせる例では、固定の入力列を使って有効な値、無効な値、終了の各経路を示しています。対話型ターミナルのプログラムでは、read_response(...) を input(...) に置き換えてください。

このセクションのコードと表示されるラベルや出力は英語のままです。

responses = iter(["oops", "7", "exit"])

def read_response(prompt):
    print(prompt, end="")
    response = next(responses)
    print(response)
    return response

while True:
    text = read_response("Enter an integer (exit to finish): ").strip()
    if text.lower() == "exit":
        break
    try:
        number = int(text)
    except ValueError:
        print("Please enter a whole number.")
        continue
    print("Accepted:", number)
Enter an integer (exit to finish): oops
Please enter a whole number.
Enter an integer (exit to finish): 7
Accepted: 7
Enter an integer (exit to finish): exit

int() を呼び出す前に番兵値を確認するため、exit が入力されると変換を試みずにループを終了します。ValueError が発生した後の continue はプロンプトに戻り、有効な整数は受け入れ側の分岐に進みます。3.5 のような小数表記は整数ではありません。小数を扱う場合は float() を使います。strip() を呼び出すと前後の空白を許容でき、lower() を使うと番兵値を大文字と小文字を区別せずに比較できます。

メニュー形式のプログラムを作る

メニュー形式のループでは、選択肢を表示し、選択内容をテキストとして読み取り、対応する処理を行ってから、明示的な終了項目が選ばれるまで繰り返します。この例では2つの整数を加算または減算します。固定の入力には、認識できない選択肢、2つの演算、終了項目が含まれています。ターミナルで使う場合は read_response(...) を input(...) に置き換え、ユーザーが任意の値を入力できるようにするなら、前の例と同じ整数の検証も追加してください。

このセクションのコードと表示されるラベルや出力は英語のままです。

responses = iter(["x", "1", "4", "5", "2", "9", "3", "3"])

def read_response(prompt):
    print(prompt, end="")
    response = next(responses)
    print(response)
    return response

while True:
    print("1) Add  2) Subtract  3) Exit")
    choice = read_response("Choice: ")
    if choice == "3":
        print("Goodbye.")
        break
    elif choice == "1":
        left = int(read_response("First number: "))
        right = int(read_response("Second number: "))
        print("Result:", left + right)
    elif choice == "2":
        left = int(read_response("First number: "))
        right = int(read_response("Second number: "))
        print("Result:", left - right)
    else:
        print("Choose 1, 2, or 3.")
1) Add  2) Subtract  3) Exit
Choice: x
Choose 1, 2, or 3.
1) Add  2) Subtract  3) Exit
Choice: 1
First number: 4
Second number: 5
Result: 9
1) Add  2) Subtract  3) Exit
Choice: 2
First number: 9
Second number: 3
Result: 6
1) Add  2) Subtract  3) Exit
Choice: 3
Goodbye.

終了の分岐は、どちらかのオペランドを尋ねる前に実行されます。認識できない選択肢が入力されると、次のメニューを表示する前に案内を出します。有効な演算ではそれぞれ2つのオペランドを読み取り、結果を表示します。同じ構造で関数を呼び出したり、設定を更新したり、情報を表示したりできます。複数の箇所で使う検証処理は、ヘルパー関数にまとめられます。

レガシーコードにおける Python 2 の入力

Python 2 はレガシーの実行環境であり、Python Software Foundation の Python 2 サンセット告知によると、2020年1月1日にサポートが終了しました。Python 2 の raw_input() は1行を読み取り、テキストとして返します。一方、input() は入力された式を評価します。これは、input() がテキストを返す Python 3 とは異なります。テキストを想定する古い Python 2 コードを保守する場合は、raw_input() を使います。Python 3 の input() の動作を Python 2 のコードに当てはめないでください。新しいプログラムでは Python 3 とその input() 関数を使いましょう。