想定読者

普段からスクリプト程度にPythonを使っていて、競技プログラミングを始める人。想定AtCoder ABCのB~くらいを解くぞ!という人向け

表示

printf構文

まず、注意することとして、フォーマット文字列はpython3.6移行の機能であるため、使えないことに注意

# Pyhton 3.6
>>> print(f'{2:02}')
02
# Python 3.5
>>> print(f'{2:02}')
SyntaxError: invalid syntax

このため、AtCoderでは従来の%構文で対応する。

# 整数表示
>>> print("[%03d] [%3d] [%+d]" % (10, 10, 10) )
[010] [ 10] [+10]
# 小数点の表示桁数制限
>>> print("%.4f" % (1/2) )
0.5000
# 小数点, 小数部をいれてn桁表示
>>> print("[%08.4f]" % (1/2) )
[000.5000]
# n文字reserveしてprintf
>>> print("[%4s] [%-4s]" % ("!", "!") )
[   !] [!   ]
# 16, 8 進数
>>> print("[%x %o]" % (255, 255) )
[ff 377]

数値

2進数

リスト操作

複数行読み込みのリスト化(内包リスト)

n = int(input())

# 内包リスト
dat_a = [int(input()) for _ in range(n)]
# 使わない場合
dat_a = []
for i in range(n):
  dat_a.append(int(input))

特定の内容だけのリスト(filter, 内包リスト)

filterを使ってもいいがlist()しないとprintはできない。

l = range(10)
# 内包リスト
print([x for x in l if x % 3 == 0])
l = range(10)
# filterのままだと <filter object at 0x000001BD4D9F18D0>になるのでlist()する
print(filter(lambda x: x % 3 == 0, l))
print(list(filter(lambda x: x % 3 == 0, l)))

# 普通に書く場合
r = []
for i in range(len(l)):
    if l[i] % 3 == 0:
        r.append(i)
print(r)

reduce

functools以下になってしまったので少し面倒。

from functools import reduce
l = range(10)
print(reduce(lambda x, y: x + y, l))

set()

l = [1,2,3,2,3,4,2,3,4,1,2,5]

# set
s = set(l)

# set化された後の追加はadd
s.add(4)

print(s)
# > {1, 2, 3, 4, 5}

print("len = " + str(len(s)))
# > len = 5

print(list(reversed(list(s))))
# reverseしたいときは一度、listに変換して、reversed objectをlistにまた戻す
# > [5, 4, 3, 2, 1]

# setはlistっぽいがlistではないのでindexは使えない。listにすること。
#>>> s[0]
#TypeError: 'set' object does not support indexing
#>>>list(s)[0]
#1

Counter:

l = [1,2,3,2,3,4,2,3,4,1,2,5]
import collections

c = collections.Counter(l)
print(c)
# Counter({2: 4, 3: 3, 1: 2, 4: 2, 5: 1})

# 昇順での頻出単語
m = c.most_common()
print(m)
# [(2, 4), (3, 3), (1, 2), (4, 2), (5, 1)]

# most_commonは昇順でのn個を引数にとる
m = c.most_common(2)
print(m)
# [(2, 4), (3, 3)]

# 最小順からの数え上げはmost_common = 昇順の結果を::-1 (逆転)してからとる
m = c.most_common()[::-1][:2]
print(m)
# [(2, 4), (3, 3)]

# こうやったほうが少し軽いかもしれない?
n = 2
m = c.most_common()[:-2-1 :-1]
print(m)
# [(2, 4), (3, 3)]

m = c.most_common(3)
print(m)
# [(2, 4), (3, 3), (1, 2)]
# ここでの注意は頭から3番目を表示しているだけで、3位タイを表示しない。上記なら(4,2)も帰ってくると思いがち

# ★辞書からの文字削除
del c[2]
m = c.most_common(3)
print(m)
# [(3, 3), (1, 2), (4, 2)]

# Subtract カウンタ同士の引き算が可能
c = collections.Counter(l)
print(c)
# Counter({2: 4, 3: 3, 1: 2, 4: 2, 5: 1})
c.subtract([5,5])
print(c)
# Counter({2: 4, 3: 3, 1: 2, 4: 2, 5: -1}) ★負にもなれる
print(+c)
# Counter({2: 4, 3: 3, 1: 2, 4: 2}) 正のカウンタのみ表示
print(-c)
# Counter({5: 1}) 負のカウンタのみ表示
print( (-c).most_common() )
# [(5, 1)] ★↑(-c)としないで-c.とすると結果が異なるので注意
print( list(map(lambda x: (x[0], -x[1]), (-c).most_common() )))
# [(5, -1)] どうしてもマイナス表記でほしいのなら↑とかかな...

namedtuple: 競技プログラミングではあまりつかわないかも

from collections import namedtuple
P = namedtuple("p", ["x", "y"])

l = []
l.append(P(0,0))
l.append(P(0,1))
print(l)
# [p(x=0, y=0), p(x=0, y=1)]

p = P(1,2)
print(p.x)
# 1

print(p[0])
# 1