uitspitss blog

プログラミングと音楽とエッセイ ※記載内容は個人の見解であり、所属する組織とは一切関係がありません。

オンラインジャッジでの Python Tips

最近、時間があるときにオンラインジャッジの競技プログラミングもどきをやっている。 オンラインジャッジでは、入出力がCLIで行われるため、 入出力周りで何度となく同じようなコードを書く。 しかし、1ヶ月くらい別の言語をいじってたりすると、 そのようなコードを書くのに少し時間が掛かってしまう。 ということで、よく使う(使った)ものをまとめておこうと思った。

input系

単純に入力が数値のときには、input()から得られたstrをintに変換しておくと、 後で数値演算したときにエラーを吐かれることがない。

int_single = int(input())  # <= 1
print(int_single) # => 1

スペース区切りで数値が複数渡されたときは、strのsplit()で分割して、 intに変換しておく。これで、ループに使うときも変換がいらない。 多重代入もよく使う。

int_list = [int(x) for x in input().split()] # <= 1 2 3
print(int_list) # => [1, 2, 3]

a, b, c = [x for x in input().split()] # <= test1 test2 test3
print(a, b, c) # => test1 test2 test3

上と同じ1行スペース区切りだが、数値文字列だけではなく、 通常の文字列も含まれていて、そのままintに投げてしまうとエラーになる。 そんなときは、内包表記内に三項演算子で条件分岐処理を入れ込む。 strのisdigit()は結構使う。

# <= l1 10 20 30\nl2 10 20 30
labeled_list = [[int(x) if x.isdigit() else x for x in input().split()] for i in range(2)]
print(labeled_list)
# => [['l1', 10, 20, 30], ['l2', 10, 20, 30]]

複数行で文字列が入力されるときは、range()ループで必要な回数分、 ループを回せばOK!

str_list = [input() for i in range(3)] # <= 1\n2\n3
print(str_list) # => [1, 2, 3]

複数行の入力がある場合かつ終了条件がある場合、 これは諦めて、while Trueループを書いちゃってる。

input_text_list = []
while True:
    input_text = input() # <= test1\ntest2\ntest3\ntest4\ninput end.
    if input_text == "input end.":
        break
    input_text_list.append(input_text)
print(input_text_list) # => ['test1', 'test2', 'test3', 'test4']

loop系

whileループやforループのelse句はよく使う。 フラグ処理が省略できるので、楽々。

cnt = 0
while True:
    cnt += 1
    for i in range(10):
        cnt += 1
        if cnt > 100:
            break
    else:
        print(cnt)
        continue
    print("last cnt: {}".format(cnt))
    break
# => 11\n22\n33\n44\n55\n66\n77\n88\n99\nlast cnt: 101

zip()は複数のリストやタプルをまとめてループできる。 それと、内包表記の多重ループ。平面グリッド走査のような全ての組み合わせでループを回すときなどで使える。 あと、文字列のjoin()もよく使う。

upper_str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lower_str = "abcdefghijklmnopqrstuvwxyz"
upper = ["{}:{}".format(u, ord(l)-32) for u,l in zip(upper_str, lower_str)]
lower = ["{}:{}".format(u.lower(), ord(l)) for u in list(upper_str) for l in list(lower_str) if u == l.upper()]

print("\n".join(upper)) # => A:65\nB:66\nC:67\n …
print("\n".join(lower)) # => a:97\nb:98\nc:99\n …