Python標準入力の基礎|競技プログラミングにも使える

Pythonでキーボードから入力を受け取る標準入力の基本的な使い方を解説。input関数からsys.stdinまで、競技プログラミングで役立つ効率的な入力処理を学べます。

Learning Next 運営
17 分で読めます

Python標準入力の基礎|競技プログラミングにも使える

みなさん、Pythonでキーボードから入力を受け取る方法を知っていますか?

「ユーザーから値を入力してもらいたい」 「競技プログラミングで効率的に入力を処理したい」 「もっと高速な入力処理をしたい」

こんな場面に遭遇したことがある方は多いはずです。 でも心配いりません!

この記事では、Pythonの標準入力について基礎から応用まで詳しく解説します。 この記事を読めば、様々な場面で適切な入力処理ができるようになりますよ。

input関数を使いこなそう

最も基本的な標準入力の方法がinput関数です。 ユーザーからキーボード入力を受け取るために使用します。

基本的な使い方

# 基本的なinput関数の使い方
name = input("名前を入力してください: ")
print(f"こんにちは、{name}さん")

このコードを実行すると、以下のような動作になります。

名前を入力してください: 田中 こんにちは、田中さん

input()関数は常に文字列として値を返します。 括弧内にメッセージを書くと、ユーザーに案内を表示できます。

数値の入力

# 数値の入力(型変換が必要)
age_str = input("年齢を入力してください: ")
age = int(age_str)
print(f"あなたは{age}歳です")
# より簡潔な書き方
age = int(input("年齢を入力してください: "))
print(f"あなたは{age}歳です")

数値として使用する場合は、int()float()で型変換が必要です。 input()で受け取った値はすべて文字列なので、計算に使う前に変換しましょう。

複数の値の入力

# 複数の値を同時に入力
data = input("名前と年齢をスペース区切りで入力: ")
name, age_str = data.split()
age = int(age_str)
print(f"{name}さんは{age}歳です")
# より簡潔な書き方
name, age = input("名前と年齢をスペース区切りで入力: ").split()
age = int(age)
print(f"{name}さんは{age}歳です")

split()メソッドを使って複数の値を一度に取得できます。 スペース区切りで入力された値を分割して取得する便利な方法です。

数値入力の基本パターン

競技プログラミングでよく使われる数値入力のパターンを学びましょう。 これらのパターンを覚えておくと、様々な問題に対応できます。

整数の入力

# 1つの整数を入力
n = int(input())
print(f"入力された数値: {n}")
# 複数の整数を1行で入力
a, b, c = map(int, input().split())
print(f"a={a}, b={b}, c={c}")
# リストとして受け取る
numbers = list(map(int, input().split()))
print(f"数値リスト: {numbers}")

map()関数を使って効率的に型変換ができます。 map(int, input().split())で、分割された文字列をすべて整数に変換できます。

小数の入力

# 1つの小数を入力
x = float(input())
print(f"入力された小数: {x}")
# 複数の小数を入力
a, b = map(float, input().split())
print(f"a={a}, b={b}")

小数の場合はfloat()を使用します。 整数と同じようにmap()と組み合わせて使えます。

文字列の入力

# 1つの文字列を入力
text = input()
print(f"入力された文字列: {text}")
# 複数の文字列を入力
words = input().split()
print(f"単語リスト: {words}")

文字列は型変換不要でそのまま使用できます。 split()で分割すれば、複数の単語をリストとして取得できます。

複数行の入力処理

競技プログラミングでは複数行の入力を処理することが多いです。 パターンを覚えて効率的に処理しましょう。

行数が決まっている場合

# 最初に行数を入力
n = int(input())
data = []
for i in range(n):
line = input()
data.append(line)
print(f"入力された{n}行のデータ:")
for line in data:
print(line)

この例では、最初に行数を受け取り、その後指定された行数分のデータを処理しています。 あらかじめ行数がわかっている場合の基本的な処理方法です。

数値の配列を複数行で入力

# 数値の配列を複数行で入力
n = int(input())
numbers = []
for i in range(n):
num = int(input())
numbers.append(num)
print(f"入力された数値: {numbers}")
# リスト内包表記を使った簡潔な書き方
n = int(input())
numbers = [int(input()) for _ in range(n)]
print(f"入力された数値: {numbers}")

リスト内包表記を使うとより簡潔に書けます。 [int(input()) for _ in range(n)]で、n回の入力を一気に処理できます。

2次元配列の入力

# 2次元配列(行列)の入力
h, w = map(int, input().split()) # 行数と列数
matrix = []
for i in range(h):
row = list(map(int, input().split()))
matrix.append(row)
print(f"入力された{h}×{w}の行列:")
for row in matrix:
print(row)
# より簡潔な書き方
h, w = map(int, input().split())
matrix = [list(map(int, input().split())) for _ in range(h)]

2次元配列の入力もよく使われるパターンです。 各行をリストとして受け取り、それを全体のリストに追加していきます。

高速入力:sys.stdinの活用

大量のデータを処理する競技プログラミングでは、sys.stdinを使った高速入力が重要です。 通常のinput()よりもはるかに高速に動作します。

sys.stdinの基本的な使い方

import sys
# sys.stdinを使った高速入力
input = sys.stdin.readline
# 使用例
n = int(input())
data = []
for _ in range(n):
line = input().strip() # 改行文字を除去
data.append(line)

sys.stdin.readlineは改行文字を含むため、strip()で除去します。 input = sys.stdin.readlineで置き換えることで、既存のコードを簡単に高速化できます。

数値入力でのsys.stdin活用

import sys
input = sys.stdin.readline
# 数値入力での使用例
n = int(input())
a, b, c = map(int, input().split())
numbers = list(map(int, input().split()))
print(f"n={n}, a={a}, b={b}, c={c}")
print(f"numbers={numbers}")

大量の数値データを処理する場合に効果的です。 通常のinput()と同じ書き方で、高速化の恩恵を受けられます。

全データを一度に読み込み

import sys
# 全データを一度に読み込み
data = sys.stdin.read()
lines = data.strip().split('
')
# 各行を処理
for line in lines:
print(f"処理: {line}")

非常に大量のデータを扱う場合に有効です。 すべてのデータを一度にメモリに読み込んで処理できます。

実践的な入力処理例

競技プログラミングでよく使われる実践的な例を見てみましょう。 これらのパターンを覚えておくと便利です。

座標の入力

# 座標の入力例
n = int(input())
points = []
for _ in range(n):
x, y = map(int, input().split())
points.append((x, y))
print(f"入力された座標:")
for i, (x, y) in enumerate(points):
print(f"点{i+1}: ({x}, {y})")

座標データの入力処理は頻繁に使用されます。 タプルとして保存することで、座標を一つの単位として扱えます。

グラフの入力

# グラフの隣接リスト入力
n, m = map(int, input().split()) # 頂点数と辺数
graph = [[] for _ in range(n)]
for _ in range(m):
a, b = map(int, input().split())
graph[a].append(b)
graph[b].append(a) # 無向グラフの場合
print(f"グラフの隣接リスト:")
for i in range(n):
print(f"頂点{i}: {graph[i]}")

グラフ問題での入力処理も重要なパターンです。 隣接リストでグラフを表現することが多いです。

文字列の格子入力

# 文字列の格子(迷路など)入力
h, w = map(int, input().split())
grid = []
for _ in range(h):
row = input()
grid.append(row)
print(f"入力された{h}×{w}の格子:")
for row in grid:
print(row)

迷路問題などでよく使われる格子の入力処理です。 各行を文字列として受け取り、文字ごとにアクセスできます。

エラーハンドリングと注意点

標準入力を扱う際の注意点をまとめます。 実際のプログラムでは、エラー処理も重要です。

型変換エラーの処理

# 安全な数値入力
def safe_int_input(prompt):
while True:
try:
return int(input(prompt))
except ValueError:
print("正しい整数を入力してください")
# 使用例
age = safe_int_input("年齢を入力してください: ")
print(f"年齢: {age}")

不正な入力に対するエラー処理も重要です。 try-except文を使って、安全に入力を受け取れます。

入力値の検証

# 入力値の検証
def validate_input(prompt, min_val, max_val):
while True:
try:
value = int(input(prompt))
if min_val <= value <= max_val:
return value
else:
print(f"{min_val}から{max_val}の範囲で入力してください")
except ValueError:
print("正しい整数を入力してください")
# 使用例
score = validate_input("点数を入力してください(0-100): ", 0, 100)
print(f"点数: {score}")

適切な範囲での入力を確保することも大切です。 値の範囲チェックも組み合わせることで、より安全な入力処理ができます。

パフォーマンスの比較

input関数とsys.stdinのパフォーマンス差を理解しましょう。 競技プログラミングでは速度が重要になることがあります。

速度の違いを理解しよう

import sys
# 競技プログラミングでの速度比較の概念
def explain_performance_difference():
"""
実際の競技プログラミングでは:
通常のinput(やや遅い):
for _ in range(100000):
n = int(input())
sys.stdin(速い):
input = sys.stdin.readline
for _ in range(100000):
n = int(input())
"""
print("大量データではsys.stdinが高速です")
print("10万回以上の入力がある場合は検討しましょう")
explain_performance_difference()

大量のデータを扱う場合はsys.stdinを使用しましょう。 特に競技プログラミングでは、時間制限があるため重要です。

競技プログラミングでの実践テンプレート

よく使われるテンプレートをまとめます。 これらをコピーして使うと効率的です。

基本テンプレート

import sys
input = sys.stdin.readline
# 基本的な入力パターン
n = int(input())
a = list(map(int, input().split()))
# 処理
result = sum(a)
print(result)

多くの問題で使える基本的なテンプレートです。 このパターンを覚えておくと、多くの問題に対応できます。

複雑な入力のテンプレート

import sys
input = sys.stdin.readline
# 複雑な入力パターン
n, m = map(int, input().split())
data = []
for _ in range(n):
row = list(map(int, input().split()))
data.append(row)
# 処理
# ここに問題に応じた処理を書く
# 結果出力
print("結果")

より複雑な入力にも対応できるテンプレートです。 2次元データや複数のパラメータがある問題で活用できます。

まとめ:標準入力をマスターしよう

Pythonの標準入力について基礎から応用まで詳しく解説しました。

重要なポイント

今回学んだ重要なポイントを整理します。

  • input関数: 基本的な入力処理に最適
  • sys.stdin: 大量データの高速処理に適している
  • 型変換: 数値として使う場合は必ず変換が必要
  • パターン: よく使う入力パターンを覚えておく

使い分けの目安

適切な方法を選ぶための目安です。

  • 通常のプログラム: input()関数で十分
  • 競技プログラミング: 問題の規模に応じて選択
  • 大量データ: sys.stdinを使用する
  • エラー処理: 実用プログラムでは必須

実践のステップ

標準入力を習得するための段階的なアプローチです。

  1. 基本マスター: input()関数の基本的な使い方
  2. パターン習得: よく使用する入力パターンの練習
  3. 高速化: sys.stdinによる高速入力の習得
  4. 応用実践: 実際の問題での活用

次のステップ

標準入力をマスターしたら、以下の内容も学んでみてください。

  • ファイル入出力: ファイルからのデータ読み込み
  • コマンドライン引数: プログラム実行時の引数処理
  • 正規表現: より複雑な文字列処理
  • データ構造: 効率的なデータ管理

標準入力をマスターすることで、より効率的で実用的なPythonプログラムを作成できるようになります。 ぜひ実際の問題で試してみてください!

競技プログラミングでも通常の開発でも、適切な入力処理は重要なスキルです。 まずは基本的なパターンから始めて、徐々に高速化のテクニックも身につけていきましょう。

関連記事