【Python】標準入力の処理【競プロ 初心者】

投稿日:
更新日:


競プロ(競技プログラミング)に挑戦したくて、paizaで練習問題をやり始めました。

どの問題でもまず必要になるのは標準入力の処理なので、忘れたときのためにカンペを作成しました。

一覧

今の時点で必要になった入力を一覧にまとめておきます。

1行

形式入力取得方法結果
文字列pythons = input()‘python’
数値123n = int(input())123
複数文字列
空白区切り
単体変数
python c#s1, s2 = input().split()s1 = ‘python’
s2 = ‘c#’
複数数値
空白区切り
単体変数
12 34n1, n2 = map(int, input().split())n1 = 12
n2 = 34
複数文字列
空白区切り
リスト化
python c#l = input().split()[‘python’, ‘c#’]
複数数値
空白区切り
リスト化
12 34l = list(map(int, input().split()))[12, 34]
文字列
1文字ずつリスト化
pythonl = [s for s in input()][‘p’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’]
数値
1桁ずつリスト化
12345l = [int(s) for s in input()][1, 2, 3, 4, 5]

n行(既知の行数)

形式入力取得方法結果
文字列
リスト化
python
c#
l = [input() for _ in range(n)][‘python’, ‘c#’]
数値
リスト化
12
34
l = [int(input()) for _ in range(n)][12, 34]
複数文字列
空白区切り
2次元リスト化
aa bb cc
dd ee ff
l = [input().split() for _ in range(n)][[‘aa’, ‘bb’, ‘cc’],
[‘dd’, ‘ee’, ‘ff’]]
複数数値
空白区切り
2次元リスト化
12 34 56
78 98 76
l = [list(map(int, input().split())) for _ in range(n)][[12, 34, 56],
[78, 98, 76]]
複数複合
2次元リスト化
1 python
2 c#
3 java
l = []
for _ in range(n):
x, y = input().split()
l.append([int(x), y])
[[1, ‘python’],
[2, ‘c#’],
[3, ‘java’]]
複数複合
辞書化
1 python
2 c#
3 java
l =
for _ in range(n):
k, v = input().split()
l[int(k)] = v
{1: ‘python’,
2: ‘c#’,
3: ‘java’}

全ての行(行数不明)

形式入力取得方法結果
文字列
リスト化
python
c#
java
import sys
l = [s.rstrip() for s in sys.stdin]
[‘python’,
‘c#’,
‘java’]
数値
リスト化
12
34
56
import sys
l = [int(s.rstrip()) for s in sys.stdin]
[12,
34,
56]
複数文字列
2次元リスト化
aa bb cc
dd ee ff
import sys
l = [s.rstrip().split() for s in sys.stdin]
[[‘aa’, ‘bb’, ‘cc’],
[‘dd’, ‘ee’, ‘ff’]]
複数数値
2次元リスト化
11 22 33
44 55 66
77 88 99
import sys
l = [list(map(int, s.rstrip().split())) for s in sys.stdin]
[[11, 22, 33],
[44, 55, 66],
[77, 88, 99]]

その他

形式入力取得方法結果
1行の複数値をintで取得1 2 3a, b, c = map(int, input().split())a=1, b=2, c=3
1行の複数値をリストで取得1 2 3l = list(map(int, input().split()))[1, 2, 3]
1行の複数値をfloatで取得1.1 2.2 3.3l = list(map(float, input().split()))[1.1, 2.2, 3.3]
1行の複数値をstrで取得a b cl = input().split()[‘a’, ‘b’, ‘c’]
1行の複数値をstrで取得し、intに変換1 2 3l = list(map(int, input().split()))[1, 2, 3]
1行の複数値をstrで取得し、floatに変換1.1 2.2 3.3l = list(map(float, input().split()))[1.1, 2.2, 3.3]
1行の複数値をstrで取得し、intに変換し、合計を求める1 2 3total = sum(map(int, input().split()))total=6
1行の複数値をstrで取得し、floatに変換し、合計を求める1.1 2.2 3.3total = sum(map(float, input().split()))total=6.6
1行の複数値をstrで取得し、intに変換し、最大値を求める1 2 3max_value = max(map(int, input().split()))max_value=3
1行の複数値をstrで取得し、intに変換し、最小値を求める1 2 3min_value = min(map(int, input().split()))min_value=1
1行の複数値をstrで取得し、intに変換し、平均値を求める1 2 3avg = sum(map(int, input().split())) / len(list(map(int, input().split())))avg=2.0
1行の複数値をstrで取得し、floatに変換し、平均値を求める1.1 2.2 3.3avg = sum(map(float, input().split())) / len(list(map(float, input().split())))avg=2.2
1行の複数値をstrで取得し、intに変換し、最大値・最小値を求める1 2 3l = list(map(int, input().split()))
max_value = max(l)
min_value = min(l)
max_value=3, min_value=1
1行の複数値をstrで取得し、floatに変換し、最大値・最小値を求める1.1 2.2 3.3l = list(map(float, input().split()))
max_value = max(l)
min_value = min(l)
max_value=3.3, min_value=1.1

複数行の取得

input関数は1行ずつ取得し、繰り返し使用することで次の行を取得していくことができる。

データの行数を始めに与えられることが多いので、大抵はfor 〜 in range(n)で1行取得する処理をn行分繰り返し呼び出して、データをリストに追加していく。

n行の文字列をリストへ

問題文でn行と指定されていたり、1行目で行数が与えられたりする場合の取得方法。

リスト内包表記で記述可能。n回inputを繰り返してリスト化する。

l = [input() for _ in range(n)]

n行の空白区切り複数文字列をリストへ

単一行で取得したものを、行数分繰り返すだけ。

リストの中に1行分のリストを追加していくので2次元リストになる。

l = [input().split() for _ in range(n)]

n行の数値をリストへ

1行取得の時と同じでintを使用し、行数分繰り返す。

l = [int(input()) for _ in range(n)]

n行の空白区切り複数数値をリストへ

こちらも1行取得の時と同じものを、行数分繰り返すだけ。

リストの中に1行分のリストを追加していくので文字列と同じく2次元リストになる。

l = [list(map(int, input().split())) for _ in range(n)]

データの行数が与えられていない時(sys.stdin)

行数がわからない場合や、または行数を指定されず全てを処理する場合は、何回繰り返せばいいか分からないため、上の方法は使えない。その場合はsys.stdinを使用する。

stdinを使用するためにはsysをimportする必要がある。

また、この方法を使用すると文字列の最後に改行文字がついてくるため、rstripが必須となる。

intに変換すると改行文字は消えるので、intにする場合はやらなくても問題なさそう。

全行の文字列を取得

for s in stdinとすることで入力が1行単位でsに代入されるので、あとはinputで取得した時と同じように処理できる。

改行を外すためにrstripをつけておく。

import sys
l = [s.rstrip() for s in sys.stdin]

全行の空白区切りの文字列を取得

上のものにsplitをつけただけ。

import sys
l = [s.rstrip().split() for s in sys.stdin]

全行の数値を取得

基本は前と同じで、intをつけるだけ。

rstripはつけなくても結果は変わらない。

import sys
l = [int(s.rstrip()) for s in sys.stdin]

全行の空白区切りの数値を取得

手順はinputの時と同じ。

import sys
l = [list(map(int, s.rstrip().split())) for s in sys.stdin]

文字列・数値の分解

1文字ずつに分解したい時がたまにある。

分解してそれぞれリストに代入する方法。

文字列を1文字ずつリストへ

for inで文字列を与えると1文字ずつ渡されることを利用してリストに入れる。

l = [s for s in input()]

数値を1文字ずつリストへ

分割した文字列にintを使うだけ。

l = [int(s) for s in input()]

データの加工

標準入力からは外れるが、ついでにメモ。

フィルターをかけて条件抽出(filter)

あらかじめ不要なデータを除いてリストに格納したいこともある。

基本の取得の方法は同じで、filter関数にラムダ式で条件を渡して抽出する。

そのままだとfilterオブジェクトになってしまうので、listでリスト化してあげる。

下の例ではn行の数値を取得し、80以下の数値のみリストに格納する。

listの部分をsortedにすることで、ソートもここで行える。

l = list(filter(lambda x: x <= 80, [int(input()) for i in range(n)]))

様々な組み合わせを検証(itertools)

与えられた入力を総当たりで検証したいこともある。

itertoolsのcombinationsを使うと簡単に重複のない組み合わせを作成してくれる。

組み合わせはタプルで返ってくるので、 まとめてリストに入れておくとforで回して処理ができる。

下の例ではlistを用いてリストにしている。

combinationsの第2引数が1つの組み合わせにいくつ含まれるかの設定になる。3なら3つ選んで組み合わせる。

from itertools import combinations
l = [list(c) for c in combinations([int(input()) for _ in range(n)], 2)]
# 入力:1〜4 を改行区切り
# 出力: [[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

itertoolsのその他の使い方

itertools --- 効率的なループ実行のためのイテレータ生成関数

終わり

問題解いてる中で新しいものに出会ったら追記する予定。

AtCoderも近いうちに挑戦したい。