dictionaryのsetdefaultとget

先日の Django Hack-a-thon で、渋川さんの発表
setdefaultとgetが便利ですよねという発表があって、
ちゃんと押さえられてないなぁと思ったので軽くまとめてみた。

user_data = {}

print user_data['user_name']

サンプルを実行させると、user_dataには、key:'user_name'が存在しないため
KeyErrorの例外が発生してしまう。


例外を発生させたく無い場合は、事前に in や has_key (in と has_key は同じ結果を返す)で、
keyをチェックして、その後処理をするのですが。

user_data = {}
# keyが存在するときだけ出力、そうでない場合は、空文字を
if 'user_name' in user_data:
  print user_data['user_name']
else:
  print ''
#if user_data.has_key('user_data'):
#  print user_data['user_name']


上記の例のようなことをしたいのであれば、getが便利。
Python 公式ドキュメントより抜粋

a.get(k[, x]) | もし k in aならa[k]、 そうでなければ xを返します
k がマップ中になくても例外を送出せず、代わりに x を返します。x はオプションです; x が与えられておらず、かつ k がマップ中になければ、 None が返されます。

上記のサンプルをgetを使って書き直すと、以下のようになります。

user_data = {}
# keyが存在するときだけ出力、そうでない場合は、空文字を
print user_data.get('user_name', '')


似たような動作で、setdefaultがあります。
指定したkeyが無い場合に、keyを辞書に追加してくれます。
Python 公式ドキュメントより抜粋

a.setdefault(k[, x]) | もし k in aならa[k]、 そうでなければ x (が与えられていた場合)を返します
setdefault() は get() に似ていますが、 k が見つからなかった場合、x が返されると同時に辞書の k に対する値として挿入されます。デフォルトで x は Noneです。

動作サンプル

user_data = {}

print '*' * 30

print user_data.get('user_name', '')
print user_data

print '*' * 30

print user_data.setdefault('user_name', '')
print user_data
******************************

{}
******************************

{'user_name': ''}


現在のポスト数 26 / 100