はじめに
この記事は、AtCoderが初めてかつPythonコーディングも全然したことがない(=新人研修やprogateとかで少しだけ学んだ)といった方向けの記事を目指しております。
すでにPythonでAtCoderのA問題くらい余裕だぜ!って方はぜひこちらの記事をお読みになっていただけると幸いです。
標準入力
文字列
S
S = input()
A, B, C
A, B, C = input().split()
$S_0, S_1, \cdots, S_{n}$
S = input().split()
$S_0$
$S_1$
$\vdots$
$S_{n}$
# 書き方1
S = []
for _ in range(n):
S.append(input())
# 書き方2
S = [input() for _ in range(n)
-
input()
で入力の受け取り。 -
split()
で指定した文字で分割(デフォルトは半角スペース)。-
split()
したらlist型になります。
-
- 改行区切りの入力に対する受け取り方は2通りあります。
- 書き方1は見やすいですが長い
- 書き方2は見づらいですが短い(リスト内包表記)
整数
N
N = int(input())
A, B, C
A, B, C = map(int, input().split()))
$A_0, A_1, \cdots, A_{n}$
A = list(map(int, input().split()))
$a_1$
$a_2$
$\vdots$
$a_{n}$
# 書き方1
a = []
for _ in range(n):
a.append(int(input())
# 書き方2
a = [int(input() for _ in range(n)]
-
input()
は必ず文字列として受け取るのでint()
で整数型に。 -
map()
はまとめて型を変換します(上の場合はいずれもint型にしています)。 -
list()
でmap()にて型変化した結果を配列にします。map()はイテレータと呼ばれる、変な文字列が返ってくるので、直接参照しない場合はlist()で直してあげます。-
map()
にて得られる結果の中身を直接指定する場合は問題ないけれど、中身をまとめて扱う場合はlist()を使ってあげないと思ってたんと違うってなります。 - イテレータはここで多く述べません(主題からずれるので)。
-
その他
$A_1, B_1$
$A_2, B_2$
$\vdots$, $\vdots$
$A_{n}, B_{n}$
# 書き方1
A, B = [], []
for _ in range(n):
a, b = map(int, input().split())
A.append(a)
B.append(b)
# 書き方2
AB = [list(map(int, input().split())) for _ in range(n)]
- 書き方1は見やすいですが長い
- 書き方2は見づらいですが短い
- 書き方2は使う時に以下のようにしてあげれば問題ないです
.pyfor A,B in AB: print(A, B)
標準出力
n
print(n)
a, b, c
print(a, b, c)
$a_1, a_2, \cdots, a_{n}$
print(*a)
$a_1$
$a_2$
$\vdots$
$a_{n}$
# 書き方1
for i in a:
print(i)
# 書き方2
print(*a)
-
print()
にて出力。 -
print()
に複数の値を入れると、半角スペース区切りで出力。 - list型の出力には
join()
を使う手法もありますが、*(アスタリスク)
をつけるだけで出力できます。-
join()
はある制約があるため、少なくともAtCoderでは使わなくて良いです(実務は別かも)。 -
*
をつける方法であるアンパックはこちらで述べません(主題からずれるので)
-
- 改行区切りの出力は2通りある
- for文で繰り返しても構わないですが、実はAtCoderでは改行区切りと半角スペース区切りの違いは精査されないです。ちょっとした裏技かも。
文字列とlist
# 文字列かlistかの違いだけ
S = "sample"
S_list = ["s", "a", "m", "p", "l", "e"]
# 実は同じ使い方ができる
print(S[0])
>>> "a"
print(S_list[0])
>>> "a"
print(len(S))
>>> 6
print(len(S_list))
>>> 6
- 文字列もlistも要素にアクセスする場合はどちらも同じです
- しかし、文字列だからできる、listだからできるという場面も多いので、完全に同じではない点に注意
- 文字列とlistが別物という認識が強すぎると、角括弧で文字列を扱うことに抵抗があるらしいです(体験談を聞いた)。
おしゃれ(?)な繰り返し処理
# listの要素を繰り返す場合
nums = [1,3,5]
for i in nums:
print(i)
>>> 1
>>> 3
>>> 5
# listの要素とインデックス番号(出現する順番)の場合
nums = [1,3,5]
for i, j in enumerate(nums):
print(i, j)
>>> 0 1
>>> 1 3
>>> 2 5
# 2つ以上のlistの要素の場合
nums = [1, 3, 5]
nums2 = [7, 9, 11]
for i, j in zip(nums, nums2):
print(i, j)
>>> 1 7
>>> 3 9
>>> 5 11
- for文は
range()
とセットなことが多いですが、listの要素に直接アクセスする方が楽だったりします。 -
enumerate()
は1回のfor文で、要素の順番が取り出せます(A問題で使ったとお聞きしたので一応紹介)。 -
zip()
は2つ以上の配列の同時取り出しに使います。この時、zip()
に渡すlistの要素数がバラバラでもエラーにならず、一番要素が少ない(=listが一番短い)listに合わせて繰り返し処理を実施します。- 例えばlist_Aは10個、list_Bは15個、list_Cは13個の要素を持つとすると、
zip()
は一番少ない10回繰り返し処理を実施したら、終了します(先頭から順に繰り返すので、list_Bやlist_Cの後ろの方が繰り返し処理の対象じゃなくなるということ)。
- 例えばlist_Aは10個、list_Bは15個、list_Cは13個の要素を持つとすると、
変数
英語しか見たことないです。個人的なルールとして、短すぎる or 長すぎるのどっちも良くないです。
- 短すぎると、AtCoderの場合は標準入力のアルファベットと被ったりするし、処理が複雑になってくると見失いがち。
- 長すぎると、いちいち入力するのが面倒です。
おすすめは英単語の先頭n文字 or 母音を削ることです。
先頭数文字の例としては、calc(=calculation)
、ans(=answer)
、num(=numer)
など。
母音を削る例としては、cnt(=count)
、idx(=index)
など。
あと1つ大事なことは すでに用意されている関数名等を使わない こと。input
やprint
を変数名にしない感覚と同じで、sum
、count
、dict
などの単語も実はPythonで用意されている関数なので避けましょう。これに関してはPythonに長く触れていると気づけるなので、最初はちょっと意識する程度で。
おわりに
僕もAtCoderを初めたばっかの時は、本番でA問題すら解けなかったことを思い出しました。記事を書くにつれて、少しずつ難易度が上がっている気がするのですが許してくださいmm
新しい環境に身を置くことになったのですが、そこでAtCoderを始めるメンバーがそこそこいたのでこの記事を書くことにしました。他にもプログラミングやAtCoderを始めたての頃につまりがちな件があればじゃんじゃんコメント書いていただきたいです。編集させていただきますので。