内包表記はリストだけではない

ということに今更気付くのは What’s old 翻訳祭りのおかげ。

Road To Python 3.x てのは What’s New を順に辿ってくとかな~り前から始まってるわけね。一番大掛かりというか時間がかかったのが int と long の統合で、これは Python 2.2 (部分的には 2.1) ではもう始まってるわけ。次が「文字列とは Unicode のことである」で、実際は 2.0 時点で「将来は Unicode のみが文字列の唯一の型になる」と言ってたりする。

とはいえ「本格的に Python 3.x と 2.x が並行」しはじめるのは Python 2.5 からで、そして「大々的に 3.0 からバックポート」が入ったのが 2.6、そして 2.7 はさらに、ベースとして 3.1 からのバックポートが入り、そして今でも 3.x からのバックポートが少しずつ入り続けてる(主にセキュリティ問題の FIX)。

バックポートだからってこともあるんだけど、こんな:

てな具合に、大々的に目立つようには書いてないのね。3.1 の方で先に気付いてた機能だけど、2.7 でも使えることにずっと気付いてなかった。

今みてみたら、チュートリアルにちゃんと書いてある(集合型辞書型)んだけど、リスト内包と違って、見出しだけ読んで出てこないのね。「リスト内包と同様に云々」と、さらっとしか書かれてない。

これね、「キーを含んだリストと値を含んだリストの2つから辞書を作る」って FAQ で、zip を使う解が良く出るんだけど、それの別解になるのよね:

 1 Python 2.7.9 (default, Dec 10 2014, 12:28:03) [MSC v.1500 64 bit (AMD64)] on win32
 2 Type "help", "copyright", "credits" or "license" for more information.
 3 >>> keys = ["a", "b", "c"]
 4 >>> vals = [1, 5, 9]
 5 >>> zip(keys, vals)
 6 [('a', 1), ('b', 5), ('c', 9)]
 7 >>> # dict のコンストラクタは (key, value), ... のリストを受け取れる
 8 >>> dict(zip(keys, vals))
 9 {'a': 1, 'c': 9, 'b': 5}
10 >>> # itertools.izip はイテレータを返すので巨大なリストから構築するには有利
11 >>> # (なお、Python 3.x では zip がもうイテレータを返すようになってるので izip は削除されてる)
12 >>> import itertools
13 >>> itertools.izip(keys, vals)
14 <itertools.izip object at 0x0000000002B2FF88>
15 >>> list(itertools.izip(keys, vals))
16 [('a', 1), ('b', 5), ('c', 9)]
17 >>> dict(itertools.izip(keys, vals))
18 {'a': 1, 'c': 9, 'b': 5}
19 >>> # zip、itertools.izip ほど「クール」にはみえなくとも、意図が伝わりやすい。
20 >>> {keys[i]: vals[i] for i in range(len(keys))}
21 {'a': 1, 'c': 9, 'b': 5}

もちろんこの場合は zip、itertools.izip を使うのがクールではあるけれどもね。

チュートリアルの例はやっぱ面白いね。

1 >>> {x: x**2 for x in (2, 4, 6)}
2 {2: 4, 4: 16, 6: 36}

これ、「重い演算をキャッシュしとく」みたいな用途を想定した例なのな。しかも、先の zip を適用する例での「2つのシーケンスから」でない例なのもいい。キーと値が直接計算の関係にあるわけね。まさにこんなときこそ「内包表記、きゃーステキ」なわけであろ。

それよりもあれだ。どうしても「長い付き合い」をしてればしてるほど「初心者向けドキュメント」を読まなくなるわけなんだけど、時々ちゃんと読み返すようにした方がいいな、チュートリアル。(FAQ もね。)

あ、あと、昨年秋くらいからかなりアタシ、翻訳プロジェクトにちょっかい出して、2.7 のクックブックが最新になってて、重要なものも増えたんで、是非ご活用してちょ。やっぱしこういったブログとかみたいなのに雑然と書いてあるより、公式ドキュメントがちゃんとしてた方がいいデショ。