Commits

Nozomu Kaneko committed f0a30eb

記事を追加

Comments (0)

Files changed (3)

+.. _defaultdict:
+
+:class:`defaultdict` がない
+==============================
+
+Python の基本的なデータ構造の1つに :class:`dict` (辞書) があります。
+:class:`dict` は別名マッピングとも呼ばれ、キーに対して値を紐付けて登録することができます。
+
+.. code-block:: pycon
+
+  >>> d = {"one": 1, "two": 2}
+  >>> d["three"] = 3
+  >>> d["one"]
+  1
+  >>> d["zero"]
+  Traceback (most recent call last):
+    File "<stdin>", line 1, in ?
+  KeyError: 'zero'
+
+上記の例の最後のように、存在しないキーを参照すると例外が発生します。
+
+これを踏まえて、ある文字列中にそれぞれの文字が何回出現したかを数える
+プログラムを書いてみましょう。
+
+.. code-block:: python
+
+  s = "abrakadabra"
+
+  d = {}
+  for c in s:
+      # d[c] += 1 としたいが、これだと最初に代入するときにエラーになる
+      d[c] = d.get(c, 0) + 1
+
+存在しないキーを参照した時のことをいちいち考えて書かないといけないので面倒です
+(間違いが多くなります)。
+
+:class:`defaultdict` を使えばすっきり書けます。
+
+.. code-block:: python
+
+  from collections import defaultdict
+
+  s = "abrakadabra"
+
+  d = defaultdict(int)
+  for c in s:
+      d[c] += 1
+
+:mod:`collections` モジュールに :class:`defaultdict` が追加されたのは
+Python 2.5 からなので、 Python 2.4 では使えません。
+
+.. note::
+
+   `Python 2.4 で使える defaultdict の実装
+   <http://code.activestate.com/recipes/523034-emulate-collectionsdefaultdict/>`_
+   もあります。
 - startswith, endswith にリストを渡せない
 - yield from が使えない
 - any, all がない
+- set リテラルが使えない
+- :ref:`defaultdict`
+- :ref:`ordereddict`
+- namedtuple がない
 
-- ordereddict がない
 - xml.etree がない
+- json がない
 - argparse がない
 - functools がない
+- sqlite3 がない
 - Python 2.4 で使えないライブラリ
 
+  - webob >= 1.1 (ok: 1.0.8)
+  - Beaker >= 1.6 (ok: 1.5.4)
+  - PasteDeploy >= 1.5.0 (ok: 1.3.4)
+  - IPy >= 0.73 (ok: 0.72)
+  - PyYAML >= 3.10 (ok: 3.09)
+  - rsa >= 3.0 (ok: 1.3.3)
+  - decorator >= 3.4.0 (ok: 3.3.3)
+
+- Exception が object のサブクラスではない
 - 相対インポートが使えない
-- Exception が object のサブクラスではない
 - セルオブジェクトに cell_contents 属性がない
 
 - True, False が代入可能
+.. _ordereddict:
+
+:class:`OrderedDict` がない
+==============================
+
+:class:`dict` の特徴は、保存したデータ量によらず検索が ``O(1)`` で行えることです。
+それと引き換えに、 :class:`dict` は保存したキーの順番を維持しません。
+
+.. code-block:: pycon
+
+  >>> d = {}
+  >>> d["zero"] = 0
+  >>> d["one"] = 1
+  >>> d["two"] = 2
+  {'zero': 0, 'two': 2, 'one': 1}
+
+すべてのキーをある決まった順番で処理したい時は、 :func:`sorted` 関数を使って
+キーをソートします。
+
+あまり意味のある例ではありませんが、キーをアルファベット順でソートする
+コードはこのようになります。
+
+.. code-block:: pycon
+
+  >>> for key in sorted(d.keys()):
+  ...     print key, "=>", d[key]
+  ... 
+  one => 1
+  two => 2
+  zero => 0
+
+キーの順番を維持してほしいケースというのは意外と多くありません。
+とはいえ、たまにあると便利なことは確かです。例えばプログラムで選択肢を扱う場合、
+表示するテキストとプログラム内部で使う値の両方を持つ必要があり、
+表示する順番も指定した通りになってくれないと困ります。こういうときは 
+Python 2.7 から追加された :class:`OrderedDict` を使います。
+
+.. code-block:: pycon
+
+  $ python2.7
+  >>> from collections import OrderedDict
+  >>> d = OrderedDict()
+  >>> d["zero"] = 0
+  >>> d["one"] = 1
+  >>> d["two"] = 2
+  >>> for key in d.keys():
+  ...     print key, "=>", d[key]
+  ... 
+  zero => 0
+  one => 1
+  two => 2
+
+`PyPI <http://pypi.python.org/pypi>`_ から :mod:`ordereddict`
+モジュールをインストールすれば Python 2.4 でも :class:`OrderedDict` を使えます。
+
+.. note::
+
+   Python の歴史上、これまでにいくつも同じような名前と機能を持つライブラリが
+   作られてきました。
+   `PEP 372 <http://www.python.org/dev/peps/pep-0372/>`_ に
+   その一覧があります。