2ヶ月前は全く Python を使えなかった私ですが、Google Code Jam の勉強を通して随分色々な技術を学ぶことができました。
ここにまとめておきます。
あまりに長くなりすぎたので3分割しました。
ファイル
標準入力から読み込む
一度に最後まで読み込みたい場合は以下のようにする。
import sys for line in sys.stdin:
1行の場合は raw_input() が簡単。
こちらは末尾に改行が入らない。
A = raw_input()
標準出力、標準エラー出力に書き出す
print は改行が入る。
print "some text"
カンマをつければ改行は入らないが空白が入る。
print "some text",
改行も空白も入れたくなければ sys.stdout を使う。
import sys sys.stdout.write("some text")
標準エラー出力は sys.stderr。
GCJ では、zibada が以下のようなテンプレートを作っている。
(出典:GCJ 2010 QR-A zibada)
def dbg(a): sys.stderr.write(str(a))
便利。私は改行を足して使っている。
with によるファイルのオープン
with open("myfile.txt") as f: for line in f: print line
行の処理中に何か問題が発生しても、最後にはかならずファイルが閉じられる。
文字列
文字列をリストに分割する
(A,B,C) = raw_input().split()
全部整数として読み込みたい場合は map を使う。
(A,B,C) = map(int,raw_input().split())
GCJ では、zibada は2つの関数を作っている。
1つ目は GCJ 2009 1C-B zibada より。
def readlinearray(foo): return map(foo, raw_input().split())
もう1つは GCJ 2010 QR-A zibada より。
def readarray(foo): return [foo(x) for x in raw_input().split()]
なぜこのような変更をしたのか不明。出力はどちらも同じはず。
文字列の長さ
len(str)
ASCIIコードと文字の相互変換
以下のコードはそれぞれ 70, F を返す。
print ord('F') print chr(70)
余談だが、linux 使っているときに ASCII コード調べたければ man ascii で一覧が出る。
案外知らない人多いと思う。
スペースを入れずに文字列を連結
print "aaa" + "bbb" + str(123)
プラスを使えばいい。ただし、連結対象は全て文字列でなければならない。
上のコードで 123 をそのまま使うとエラーになる。
よく忘れるので注意すること。
ループで1文字づつ展開する
for c in word:
これで1文字づつ取り出せる。
php の join() や ruby の Array.join() のように join を使う。
php や ruby と違い、python のリストには join() がない。
しかし、以下の形で文字列として連結することができる。
s.join(q)
ここで s は文字列、q はシーケンス。つまりリストでも構わない。
s が区切り文字になるので、例えば空文字で ''.join(q) のように書けば、完全に並んだ文字列にしてくれる。
ただし、シーケンス中の要素は全て文字列でなければいけない。
たまに整数のリストをそのまま join しようとしてはまることがある。
そういうときは map() でも一枚噛ましてやればいい。
lstrip,rstrip,strip
それぞれ行頭、行末、その両方から特定の文字を除去したコピーを返す。
指定しない場合は空白文字全て。
引数は文字列で指定し、そこで指定された全ての文字が除去される。順序は無視。
正規表現
re.match と re.search
search を使うと、開始位置が文字列中にあってもマッチする。
match の場合はきちんと文字列中にあることを明示しない限りマッチしない。
逆に言うと、先頭にだけマッチさせたい場合は match で書く方が簡単。
後方参照
\\1 とすること
置換
p = re.compile(regexp)
line = p.sub(replace,target_str)
辞書
ループで添字も一緒に取り出す
for k,v in dict.iteritems():
ループ時に value でソート
for k, v in sorted(d.items(), key=lambda x:x[1]): print k, v
get()
dict[key] という形式で存在しないキーを指定すると KeyError が出される。
しかし dict.get(key) とすれば、キーが存在しないときに None を返す。
dict.get(key,x) とした場合、キーが存在しないときに None ではなく x を返す。