辞書って便利!

辞書の活用どころ。

tags:python, tips, experiment, dict
created:2007-02-05T20:24:24

辞書の活用どころ。 Perlの連想配列をPythonでは辞書(dictオブジェクト)と呼びます。

基本

初期化、参照、追加、削除は以下のような感じ。

>>> dic = {'hoge': 123, 'moge': 456}
>>> dic['hoge']
123
>>> dic['h'] = 666
>>> dic
{'h': 666, 'moge': 456, 'hoge': 123}
>>> del dic['moge']
>>> dic
{'h': 666, 'hoge': 123}

「 { 」と「 } 」で囲めば辞書オブジェクトを作成できます。

中には「キー:バリュー」のセットをカンマで区切って任意の数を格納できます。

注釈

Pythonではキーの型は、辞書オブジェクト全体で同じ型である必要がありません。 キーはPython内部で「型と値から生成されるオブジェクトハッシュコード」で管理されるようです。 ただし、キーに使えるオブジェクトはイミュータブル(変更不能)オブジェクトでなくてはなりません。 (文字列やタプル、数値など)

空の辞書

からっぽの辞書は以下のように書きます。

>>> dic = {}
>>> dic
{}

スコープ辞書

以下のビルトイン関数は、記述時点でのアクセス可能なオブジェクト群をスコープ別に辞書として返してくれます。

  • vars():ローカルスコープにあるオブジェクト群(locals()と違いがあるのだろうか?)
  • locals():ローカルスコープにあるオブジェクト群
  • globals():locals()をグローバルスコープにあるオブジェクト群
>>> dic={}
>>> vars()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'dic': {}}

といったように、dicという名前のキーをもつ辞書オブジェクトが含まれている事が確認できます。

>>> print dic
>>> print vars()['dic']

上記の1行目、2行目は同じ結果となります。

このように、Pythonではすべてのオブジェクトは名前をつけた上で辞書によって管理されています。

注釈

Pythonでは宣言した関数やクラス、インポートしたモジュールもオブジェクトなので、それらもグローバル辞書に含まれます。

リストを辞書に

「2つのオブジェクトのリストかタプル」のリストに対し、「dict」キャスティングを行うと辞書化できます。

>>> dic=dict([['hoge',123], ['moge', 456]])
>>> print dic
{'moge': 456, 'hoge': 123}

また、別個のリスト2つから、上記のようなセットを作れる「zip」というビルトイン関数を使うと、 以下のような変換ができます。

>>> dic=dict(zip(['hoge', 'moge'],[123, 456]))
>>> print dic
{'moge': 456, 'hoge': 123}

逆に辞書からリストに

定番の「dir」に辞書オブジェクトを渡してみましょう。

>>> dic = {'hoge': 123, 'moge': 456}
>>> dir(dic)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__'
, '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '
__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__re
duce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', '
clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys',
'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
dic.items()
タプルのリストを返す。
dic.keys()
キーだけのリストを返す。
dic.values()
バリューだけのリストを返す。

かようなメソッドが用意されていますので、逆変換は簡単ですね。

注釈

iterXXXX系も同様の結果が得られますが、イテレータオブジェクトを中継します。 イテレータの使い方はまたいずれ・・・(Webにはいっぱい例がありますよね)

書式化文字列への応用

Pythonでは文字列にモジュロ演算(%)を行うとフォーマッティング文字列を作成できます。

>>> fname = 'test.log'
>>> print "loading... [%s]" % fname
loading... [test.log]

C言語でいうところのprintfとほぼ同様の記述が使えます。

>>> fname = 'test.log'
>>> date = '2005-09-29'
>>> print "file:%s(%s)" % (fname, date)
file:test.log(2005-09-29)

複数のパラメータがあるときは上記のようにタプルを使います。

で、本命ですが、辞書を演算子の右に書いた場合、置き換え要素を書式化文字列に明記する形が使えます。 「%s」を「%(fname)s」という風に記述すると、 指定した辞書のなかから「fname」という文字列キーで値を取り出し、 この記述部分はその値に置き換えられます。

>>> fname = 'test.log'
>>> date = '2005-09-29'
>>> print "file:%(fname)s(%(date)s)" % vars()
file:test.log(2005-09-29)

この形を使うと、長い書式化文字列の中で反復して辞書要素を差し込む事ができます。

>>> fname = 'test.log'
>>> print "file:%(fname)s...%(fname)s" % vars()
file:test.log...test.log

こんなかんじ。

もちろん直接辞書をその場で指定することもできます。

>>> print "Detected %(b)d count(s) for %(a)s." % {'a': 'hoge', 'b':123}
Detected 123 count(s) for hoge.

また、「os」モジュールには環境変数を辞書化したオブジェクト「os.environ」があります。

「COMPUTERNAME=(ホスト名)」という環境変数があるなら・・・

>>> import os
>>> print "Host:%(COMPUTERNAME)s" % os.environ
Host:(ホスト名)

こんな使い方ができます。CGIを作る時に便利ですね。

結論

Pythonでは、いろんなところでこの辞書オブジェクトが活躍しています。 ぜひ今回紹介した基本を知っておいてからいろんなPythonソースコードを読んでみてください!