はじめに
Pythonを学習するにあたって、せっかくなので、Pythonらしい書き方というものを調べてみました。
Pythonらしさは、Pythonの効率の良いコードと同意だからです。
参考にしたスライド
https://speakerdeck.com/pyconslides/transforming-code-into-beautiful-idiomatic-python-by-raymond-hettinger-1
http://kesin.hatenablog.com/entry/2013/05/12/004541
辞書の使い方
これぞPython
らしさというもので、辞書の使い方は非常に重要かつ基本的なテクニックです。
何かとお世話になる辞書には、うまいやり方がありそうです。
キーでループ
辞書を指定しても、辞書オブジェクトのkeys
メソッドを使っても、キーでのループが可能です。
d = {'kaijo': 'red', 'shinmei': 'blue', 'ooiwa': 'yellow', 'pegie': 'pink', 'asuka': 'green'}
for k in d:
print(k)
for k in d.keys():
print(k)
キー、バリューのループ
キーと値とをループさせる方法としては、上段のキーによるループをして、キーから値を取得する方法が考えられます。
Pythonの辞書にはitems
メソッドがあり、これを利用することで、辞書からキーを用いて値を取得することが必要なくなります。また、値の変数が自由に決められるため、読みやすいコードになります。
d = {'kaijo': 'red', 'shinmei': 'blue', 'ooiwa': 'yellow', 'pegie': 'pink', 'asuka': 'green'}
for k in d:
print(k, '->', d[k])
for k, v in d.items():
print(k, '->', v)
辞書を2つのリストから作成する
キーのリストと値のリストが既にあるような場合では、これらを合成することで辞書を作成することができます。
for
文を使わずにできます。
from itertools import izip
keys = ['kaijo', 'shinmei', 'ooiwa', 'pegie', 'asuka']
values = ['red', 'blue', 'yellow', 'pink', 'green']
d = dict(izip(keys, values))
インデックス的な連番をつけた辞書にしたい場合はenumerate
を使うと作成できます。
values = ['red', 'blue', 'yellow', 'pink', 'green']
d = dict(enumerate(values))
辞書を使ったカウント
英語の文章に同じ単語がいくつ出現するか、などの処理をするときには、以下のような処理が想像しやすいです。
colors = ['red', 'green', 'red', 'blue', 'green', 'red']
d = {}
for color in colors:
if not color in d:
d[color] = 0
d[color] += 1
辞書のget
メソッドは指定したキーがいくつあるかを返しますが、キーがない場合は、引数で与えた値を返します。
それを利用して以下のように書けます。
colors = ['red', 'green', 'red', 'blue', 'green', 'red']
d = {}
for color in colors:
d[color] = d.get(color, 0) + 1
collections
モジュールのdefaultdict
は、キーがない場合に追加する機能を持っています。
それを利用して以下のようにも書けます。
get
を使うより読みやすくなります。
from collections import defaultdict
colors = ['red', 'green', 'red', 'blue', 'green', 'red']
d = defaultdict(int)
for color in colors:
d[color] += 1
辞書を使ったグルーピング
例えば単語のリストがあったとして、単語の文字数でグルーピングしたいといったような場合には、わかりやすいコードとして、キーがないときにデフォルト値(この場合は名前を格納するリスト)を設定する方法があります。
デフォルト値を格納するところはsetdefault
メソッドが使えます。
names = ['raymond', 'rachel', 'matthew', 'ronger', 'betty', 'melissa', 'judith', 'charlie']
d = {}
for name in names:
key = len(name)
if not key in d:
d[key] = []
d[key].append(name)
d2 = {}
for name in names:
key = len(name)
d2.setdefault(key, []).append(name)
これを先程のdefaultdict
を使うと以下のように書けます。
if
文がなくなってエレガントになりました。
from collections import defaultdict
names = ['raymond', 'rachel', 'matthew', 'ronger', 'betty', 'melissa', 'judith', 'charlie']
d = defaultdict(list)
for name in names:
key = len(name)
d[key].append(name)