見出し画像

Pythonのinput()について【競プロ】

Pythonで競プロのような問題を解く際に、input関係でエラーを起こしてしまいがちなので、備忘録として残しておきます。プログラミング超初心者(特に筆者)向けに書いています。


input()の簡単な仕様

使う前に一旦変数に入れるパターンが多いでしょう。input()を使う前にその変数の宣言をする必要はありません。

# 変数 = input()
s = input() # 標準入力をstrに格納

例えば、標準入力が
Hello world
のとき、sにはstr型(文字列型)で"Hello world"が入ります。
では、標準入力が
3
のときはどうでしょう。このときはstr型で3が入ります。標準入力の値が数値のつもりであっても、Pythonにはただの文字列として認識されてしまいます。これの解決策については後述します。

また、input()は空白区切りではなく、1行ごとに読み込みます。
例えば標準入力の値が
3 45 2
のとき、上のコードでいうsに入る値は、3 ではなく"3 45 2"です。

input()を使いこなす

数値として扱う

問題を解く際に、標準入力を数値として扱いたいことが多いですね。そんなときはint()で整数型に変換してやりましょう。

# 変数 = 変換先の型(input())
s = int(input())

inputで取得した値をintで整数に変換しています。これで、s*3のような処理も問題なく行えます。

空白区切りで取得する

空白区切りで取得するには、.split()をお尻につけましょう。

s = input().split()

このときsはリストとなります。リストはC言語における配列と同じものと思って差し支えありません。多分。
例えば、標準入力が
3 57 4
のとき、sをprintすると
['3' , '57', '4']
となります。

空白区切りのa個の入力をa個の変数に格納する

# 入力が4つのとき
s, t, u, v = input().split()

例えば、入力が
3 6 22 hello
のときはそれぞれ、
s = "3"
t = "6"
u = "22"
v = "hello"
となります。

空白区切りで取得した要素を数値として扱う

先ほどのリストに格納された要素は、すべて文字列型です。これらの要素を整数型に変換したいときには、int()で囲ってはいけません。

s = int(input().split()) # 標準入力は 3 2 1

このコードを実行すると、こんなエラーが出ます。

Traceback (most recent call last):
  File "./Main.py", line 1, in <module>
    s = int(input().split())
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

ここで注目したいのは一番下の行、TypeErrorです。これを直訳すると、
TypeError: int() の引数は、文字列、バイトのようなオブジェクト、または数値でなければならず、 'list' ではありません。
となります。家に例えると、「全部の部屋にコンセントを付けたいのに、家がコンセントになっちゃうよ!」みたいなことです。イミフですね。

これを解決するには、map()を使います。

# 変数 = map(変換先の型, input().split())
s = map(int, input().split())

これでsに整数型の値が入りました。ただ、これだけでは不十分です。なぜなら、このときのsは”mapオブジェクト”というのになっていて、sの中の要素を取り出して処理したいときに不便です。
というわけで、list()を使います。

# 変数 = list(map(変換先の型, input().split()))
s = list(map(int, input().split()))

これでmapオブジェクトをリストに変換できました。だいぶややこしくなってしまいましたが、これが一番扱いやすい形だと思います。

ちなみに、リストに格納せずに、それぞれ別の変数に格納するなら次のようにすれば十分です。

# 3変数の例 入力の数に応じて変えなければならない。
a, b, c = map(int, input().split())

複数行にわたる入力を受け取る

複数行入力させるにはfor文を使います。競プロでは基本的に標準入力で必要な行数がNのような値で与えられると思うので、そのことを前提とします。

行数をNとし、処理したい値をa_? とします。
標準入力は以下のように与えられます。
N
a_1
a_2

a_N

N = int(input()) # 必要な行数
inputList = [] # リスト inputList の定義. 標準入力の値をこのリストに入れる
for i in range(N):
   inputVal = input() # 標準入力から来た一行の入力をいったん入れる
   inputList.append(inputVal) # リストの名前.append(追加したい値) でリストに要素を追加

このようにして受け取れます。
コードにコメントを残してあるので説明は省きます。
for文の中身を inputList.append(input()) としても良いのですが、この後説明する行列の入力でややこしくなるので、ここではいったんinputValという変数に格納します。

行列を入力する

行列を扱う問題では次のように標準入力が与えられることが多いと思います。
N行M列のデータが与えられる。
N M
a11 a12 a13 … a1N
a21 a22 a23 … a2N

aM1 aM2 aM3 … aMN

この入力を受け取るコードの一例を示します。改良の余地はたくさんあると思いますので、その際にはコメントなどで知らせていただけると幸いです。

# 行の入力
N = list(map(int, input().split())) # Nの中身: [N,M]
N = N[0] # Nの中身: N

inputMatrix = [] # 行列を格納する配列(この時点では1次元配列)

# 行列の入力
for i in range(N):
   inputVal = list(map(int, input().split()))
   inputMatrix.append(inputVal) # リストの中にリストを格納するので二次元配列となる

列の数Mは使わないので、面倒ですがNとMを両方inputしてからNで上書きしています。Mを使用する場合は適宜コードを変えてください。
inputMatrixという一次元リストを定義して、標準入力から取得した1行ごとのデータをリストに変換し、inputMatrixに格納する(リストの中にリストが入るので、2次元リストとなる)という内容になっています。

この記事が気に入ったらサポートをしてみませんか?