Python2で競技プログラミングする時に知っておきたいtipsの,入出力の部分を分割しました.
Pythonで競技プログラミングをする際の入出力手法について例示する.
入出力のコードは,言語を初修する際のハードルになることが多いが,一度覚えてしまえばワンパターンなのでさっさと覚えてしまいたい.
Pythonのバージョンは2.7.5(Python3では,入出力などの仕様が大きく異なるので,他の記事を参照することをおすすめします).
参考
1行に文字列1つの入力
形式
S
Sは文字列.
入力
S = raw_input()
1行に整数または浮動小数点数1つの入力
形式
N
Nは整数または浮動小数点数.
入力
N = input()
1行にスペース区切りで複数の文字列の入力
形式
A B C
A,B,Cは,いずれも文字列.
入力
l = raw_input().split()
print l[0] # Aの値が出力される
print l[1] # Bの値が出力される
print l[2] # Cの値が出力される
split()
は,スペース区切りで文字列をリストに分割する.
1行にスペース区切りで複数の整数または浮動小数点数の入力
形式
A B C
A,B,Cは,いずれも整数または浮動小数点数.
入力
すべての変数をリストに代入したいとき
A,B,Cがすべて整数の場合は,
l = map(int, raw_input().split())
print l[0] # A
print l[1] # B
print l[2] # C
要するに,文字列型で受け取った入力をスペースで分割してリストに代入し,各要素を整数型にmapするということ.
要素の数が入力データに与えられることがあるが,Pythonの場合は使わなくてもさほど問題にならない.
浮動小数点数の場合は,
l = map(float, raw_input().split())
浮動小数点数の場合にint
を使うと,値が切り捨てられてしまうので注意.
それぞれを別の変数に格納したい場合
A, B, C = map(int, raw_input().split())
print A # A
print B # B
print C # C
リストの要素数が左辺の数に一致していれば,左辺それぞれの変数にリストの各要素を代入できる.
こういう形式の代入を「アンパック代入」というらしい.
競技プログラミングの場合,入力の要素数が明らかで,かつ少ない場合のみ使うとよい.
あまり見かけないが,1行に文字列や整数が混在している場合は,とりあえず1行を文字列として受け取り,後でint()
,float()
などを用いて変換する.
複数(N)行それぞれに1つの整数の入力
形式
N
a1
a2
a3
...
aN
a1,a2,...,aNは,N個の整数.
入力
N = input()
a = []
for i in range(N):
a.append(input())
print a # [a1, a2, a3, ..., aN]
これでいい.
@zakuro9715さんに教えていただきました.
このコードは,リスト内包表記を用いて,以下のようにも表せる.
N行入力が1行で書けてキレイ.
N = input()
a = [input() for i in range(N)]
print a # [a1, a2, a3, ..., aN]
複数行(特定の整数を受け付けるまで)それぞれに1つの整数の入力
Aizu Online Judge (AOJ)とかでよく見る形式.
形式
a1
a2
a3
...
-1
a1,a2,...,はいずれも整数.
-1が入力の終わりを表す.
入力
a = []
while True:
n = input()
if n == -1:
break
a.append(n)
print a # [a1, a2, a3, ..., aN]
複数行(入力の終わりまで)それぞれに1つの整数の入力
これもAOJでたまに見る.
デバッグもしづらいし,個人的には嫌いな形式.
形式
a1
a2
a3
...
(EOF)
a1,a2,...,はいずれも整数.
EOFが来るまで読む.
入力
import sys
a = []
for line in sys.stdin:
a.append(int(line))
print a # [a1, a2, a3, ...]
複数(N)行それぞれにM個の整数の入力
今までのまとめ的な感じ.
形式
N M
a11 a12 a13 ... a1M
a21 a22 a23 ... a2M
a31 a32 a33 ... a3M
...
aN1 aN2 aN3 ... aNM
a11,a12,...,aNMは整数.
入力
N, M = map(int, raw_input().split())
a = []
for i in range(M):
a.append(map(int, raw_input().split()))
print a
# [[a11, a12, a13, ..., a1M]
# [a21, a22, a23, ..., a2M]
# ...
# [aN1, aN2, aN3, ..., aNM]]
たぶん,これぐらいおさえておけば困らない.
ジェネレータを使った汎用的な入力
@t2y さんに教えていただきました.
ジェネレータを用いることによって,複数行に渡る入力をうまく受け取ることができる.
例えば,
形式
a1
a2
a3
...
(EOF)
a1,a2,...,はいずれも文字列.
EOFが来るまで読む.
のような形式であれば,
def get_input():
while True:
try:
yield ''.join(raw_input())
except EOFError:
break
if __name__ == '__main__':
a = list(get_input()) # [a1, a2, a3, ...]
のようにする.
他にも,get_input()
の内容を,
def get_input():
while True:
try:
s = raw_input()
if s == '-1':
break
yield ''.join(s)
except EOFError:
break
と変えることで,「"-1"を読むか入力の終わりまで」といった若干複雑な入力を受け取るといったこともできる.
出力
1変数を出力(改行あり)
形式
A
末尾に改行を含む.
出力
print A
整数型でも文字列型でも出力できる.
他にも,リストやディクショナリなどのデバッグもprint文でそのままできる.
1変数を出力(改行なし)
正直見たことがないが,一応勉強のために.
形式
A
末尾に改行を含まない.
出力
import sys
sys.stdout.write(A)
複数変数をスペース区切りで出力
これはよく見る.
形式
A B C
末尾に改行を含む.
出力
print A, B, C
print文では,変数の後に,
を入れると,改行が半角スペースに変換される.
Python Tips:改行なしで文字列を出力したい - Life with Python
複数変数をカンマ区切りで出力
形式
A,B,C
A,B,Cはいずれも文字列.
末尾に改行を含む.
出力
print ','.join([A, B, C])
join()
は,split()
の逆の演算に相当し,引数の文字列のリストの各要素をレシーバの文字列で結合したものを返す.
リストのすべての要素が文字列型でなければならないことに注意.
ここで,例えば,A,B,Cが整数だったとすると,
print ','.join(map(str, [A, B, C]))
のように,str()
によって各要素を文字列に変換してからjoinする.
フォーマットにしたがった出力
C++におけるprintf関数のように,自由な形式での出力がしたい場合がある.
形式(例)
Case 1: A B
A,Bはいずれも整数.
末尾に改行を含む.
出力
print 'Case 1: {0} {1}'.format(A, B)
format()
は可変長の引数を受け取り,i番目の引数の値を'{i}'に格納した文字列を返す.
出力時の基数変換や桁揃えなど,printfでできるだいたいのことがformat()
でもできる.
詳しくは,リファレンスを見るとよい.