作者: 機械伯爵
日時: 2005/11/21(08:59)
PはPythonのP ---P IS FOR PYTHON--- 06h

WISE MAN #2: We wish to praise the infant.
WISE MAN #1: We must pay homage to him.
MANDY: Homage? You're all drunk. It's disgusting.
    Out! The lot, out!
WISE MAN #1: No--

賢者その2「我らはその幼子を賛美したいのです」
賢者その1「我らは彼に、帰依したいのです」
マンディー「帰依? あんたらみんな酔っ払いだね。ムカつく。
    でてけっ! も〜うんざり、でてけっ!」
賢者その1「や、やめてくれっ!」

by "MONTY PYTHON'S LIFE OF BRIAN"

■登場人物

朽縄 巽(くちなわ たつみ)
 プログラマな高1の少年。生徒会会計。

大鳥翔子(おおとり しょうこ)
 巽の幼なじみ。高2。生徒会長。

木崎美央(きさき みお)
 巽のクラスメイト。生徒会書記。

天美修也(あまみ しゅうや)
 生徒副会長。高2。

坂下望美(さかした のぞみ)
 巽のクラスメイト。新聞部員。

0000-0110.辞書も歩けば、生き字引

 私立鳳龍学院高等学校は、『自由・自律・自治』を建
学の精神とする、一風変わった高校である。
 学校運営に於ける生徒自治会の影響力が非常に強く、
学校規則 (校則) の制定/改定などにも意見・提案でき
る権限を持つ。
 生徒自治会 (生徒会) は、実際に自治会運営を行う執
行部の他に、各HR (ホームルーム) から2名づつ代表
が選出される生徒議会、主に学級運営に携わるHR委員
(室長/副室長)によるHR部会、独立権限を持つ独立
報道局 (報道局) で構成される。
 執行部は、執行委員長 (生徒会長) 1名、執行副委員
長 (副会長) 1〜2名 (委員長により任命され、その裁
量により1名か2名か決定できる)、書記官 (書記) 1〜
2名、会計官 (会計) 1〜2名、および5〜 10 名の執
行委員から構成される。
 独立報道局は、主に連絡事項通達業務の他、執行部批
判を行う権限を持ち、新聞部・放送部の2部門に分かれ
る。
 新聞部には編集長1名、副編集長は必要に応じ0〜2
名、部員は5名以上。
 放送部には部長1名、部長補0〜2名、部員5名以上。
 また、報道局には局長1名、副局長1名が常任するが、
編集長と放送部長がそれぞれ兼務することが通例である。
 教師で構成する生徒指導部は、生徒自治会に対し、司
法の立場を取る。
 その他大きな特長としては、校内風紀は生徒による生
活委員が基本的に管理し、原則的に教師による生活指導
部は、規則違反者の処分時のみ関与するというシステム
がある。
 自治による効果は、この学校の特異的ないじめ件数/
不登校件数の少なさに反映している。
 なお、学業成績については飛びぬけて特記すべきとこ
ろはないが、これも成功率よりも個々の希望を重視し、
そのサポートをするという体制を取るため、各人が概ね
満足できるところに進学・就職していると学校案内パン
フレットには記載されている(事実はともかく)

    ☆   ☆   ☆

「君が朽縄くんか」
 朽縄巽は、なぜかまた報道局新聞部編集室に呼ばれて
いた。
 今回は、仕事を片付けている木崎美央抜きだが、暇そ
うにしていると仕事を言いつけられる執行部室にいるよ
りマシか、と、気楽に応じたのだ。
 呼び出したのは、2年の新聞部編集長の来生章介(き
すぎ しょうすけ)だ。
 なんとなくのんびりとした風貌とは裏腹に、とんでも
ない曲者だと大鳥翔子は説明していた。
「いやぁ、君の作った集計システム、重宝させてもらっ
てるよ。単に処理が早くなっただけじゃなく、解析用デー
タまで吐き出してくれるなんて、有難いことだ」
「じゃ、前のシステムに不具合があったとか、そういう
理由で呼ばれたんじゃないんですね?」
「勿論違うよ」
「一安心です」
 そのやり取りを端でにやにやしながら見ていた坂下望
美が、口を挟む。
「朽縄くんの仕事は完璧よ。寧ろ、使いやすいってみん
なから感謝の言葉が出てるわ」
「ホント?」
「ホントホント」
 来生も頷く。
「坂下の言う通りだよ。うちの部員の中にもコンピュー
タに強い奴はいるけど、君みたいに自在にプログラムが
書ける人間はさすがに居ないからね」
 巽は、仕事を喜んでもらえたことを満足しつつも、特
別扱いに少し不満を表明する。
「昨今のプログラミング環境は簡単なんですよ。昔みた
く、職人じゃないととうてい作れないなんてシロモノじ
ゃないです」
「そうなのか」
「ええ。それに僕の親父に聞いた話では、パソコンって
いう言葉が流行り出した頃は、パソコンユーザ・イコー
ル・プログラマだったそうです。OS は Windows じゃな
くって BASIC だったみたいですしね」
「BASIC って、プログラミング言語じゃないのか?」
「今ではそうですが、昔は実際のアプリケーションを動
かす基本ソフトウェアですから、OS って言った方がニュ
アンスが近いですね」
 例えば、8bit のディスクベース OS として有名な CP/M
や、その後パソコン OS 界を支配した MS-DOS は、シェ
ルを含み単体でプログラミング及び実行可能な UNIX の
ような意味での OS と言えるかどうかは、難しいところ
がある。
「朽縄くん、それ、いつの話よ」
 望美がつっこむ。
「えっと、80年代前半くらいかな?」
 約四半世紀前である。
「そんな、あたしたちが生まれるずっと以前の話なんて、
知らないわよっ!」
「いや、その頃の人が、ずっとチープな環境でプログラ
ミングしながら作業してたんだから、コンピュータに慣
れて、さらにプログラミング環境まで格段に良くなった
今、できないはずは無いと思うよ」
 しかし、プログラマの数は、パソコンユーザの数に比
べてそんなに増えていない。
 割合としては、勿論激減している。
「ねぇ朽縄くん。今の人って、お釜でご飯炊けると思う
?」
 アイロニーを持ち出す望美。
 しかしそういう手法は、人を間違えるとかえって話が
ややこしくなる。
「炊けるんじゃないの?」
 見事に間違えたらしい。
「普通は炊けないわよ。アレ、火加減難しいのよ。つま
り、現代人の知識って、実用的なものは昔の人より減っ
てるって、わかってる?」
「そうなの?」
「そうなのっ! だから、朽縄くんみたいなのは、言わ
ば『伝統工芸』の職人なのよ」
 今度は巽がムキになる。
「んな大袈裟な。プログラムなんてキー叩けば誰でもで
きるから、手先の器用さなんて関係無いじゃない。それ
に、どう押したって同じ字が出るから、ピアノみたいな
難しさも無いしね」
 そういう話ではない。
「あっそう。じゃ、ワープロは誰でも打てるわね」
「僕は滅多に使わないけど」
「じゃ、文書は何で作ってるのよ」
「テキストエディタと写植ソフト」
 望美はなんだか、翔子の気持ちがわかってきた。
「使わなくても、打てるわね?」
「多分」
「じゃ、そのワープロ使って、ベストセラー小説書ける?」
「無理だよ」
「でしょ?」
 だから、といいかけた望美に、畳み掛けるように話し
掛ける巽の内容は、完全に彼女の予想を逸脱していた。
「だって、ワープロソフトって、10分も使ってるとイラ
イラするもん。いらない機能が一杯で、それ解除するの
にメニュー引っ掻き回したりしてたら、そのうち『なん
でこんな苦労してまでわけのわからん出来損ないソフト
ウェアにつきあわなきゃならないんだっ!』って思って、
で、多分原稿用紙1枚も書かないうちに投げ出すと思う」
「……………そういう話、してると思う?」
「そうじゃないの?」
「本気?」
「うん」

    天然か、こいつわ

 望美の背筋に、じわっっと冷や汗が広がる。
「じゃ、紙と鉛筆でも………」
「紙と鉛筆だと、原稿用紙十枚が限度じゃない? タダ
でさえ授業でノートとって指痛いのに。ホント、授業の
ノートなんか、パソコンで取らせてくれればいいのに…
……」
 ここで、望美の堪忍袋の緒がキレた。
「そういう話じゃないっ! 道具があったら、小説書け
るかって話しっ! 違うでしょ? 文字打つ能力と小説
書く力、明らかに違うでしょっ!」
「いや、僕は小説とか書いたこと無いし。そんなこと言
われても………」
「じゃ、今書きなさいよ。文字が書けるなら、小説書け
る筈でしょ?」
「別に書きたくないし」
「書きたかったら書けるわけっ!?」
「書きたくなってみないと、わかんないなぁ」
 望美は、巽の襟首を掴んで吊るし上げる。
「あんたは常識って無いのっ! なんでこんなにマトモ
に話できないのっ! あんた、おかしいわよっ!」
「常識などというものが存在すると思う方が間違いなの
だよ」
 がらりと引き戸を開きざま、天美修也は、いきなり会
話に割り込んだ。
「あ、天美先輩」
 文字通り吊るし上げを食らいながら、巽が片手をあげ
て合図する。
「ふむ、朽縄くんが新聞部に拉致されたと聞いて、冷や
かしに来たのだが」
「冷やかしですか」
「うん」
 完全にタイミングで毒気を抜かれた望美が、へなへな
とその場に座り込む。
「しかし、拉致だけではなく、拷問されてるとなれば、
これは問題だよなぁ、来生」
 新聞部編集長は、苦笑いするしかなかった。
「いや、確か彼の腕を誉めてただけだと思ったのだけど、
どうしてこうなったのやら」
「誉めていかがする?」
「いや、こっちのシステム作ってくれたんで、お礼にお
茶でも出そうかと」
「ふむ、でも、茶も茶菓子も出てないようだが」
「これから出す予定だったんだよ」
 言いながら来生は、後ろ暗いところがまるでないにも
かかわらず、言い訳しているような気分になってきた。
「しかし、もてなすのと、部下を使った虐待とでは、天
と地ほどの差があると思うのだが」
「だから、どうしてこうなったのか、俺にもよくわから
んのだよ」
「一部始終見ていたのではないのか?」
「見ていた………んだよな、確かに」
「では、放置することでイジメに荷担を………」
「人聞きの悪いことを言うな」
「では、説明してみよ」
「それは………」
 説明できなかった。
「ともかく、朽縄くんは連れて帰るぞ」
「ああ」
 執行部の二人が出て行ったところで、来生はふぅーっ
とため息をついた。
「なんとか説得して、朽縄くんをスカウトするはずだっ
たのに、何故こうなったんだろうな?」
「………」
「坂下、お前が一番乗り気だったんじゃないか。そのお
前が喧嘩してどうする?」
「………」
「ま、なんか朽縄くんは堪えてなかったみたいだけど、
天美に警戒されたし、ダメかな」
「……………逃がしません」
「ん?」
「逃がしません。あんなボケ男、放置しておくのは、あ
たしのプライドにかかわります。ああいう非常識人間は、
捕獲して調教すべきです」
「おいおい冗談は………」
 言いかけて、虚ろに宙を見ている望美の目に狂気の色
を認め、来生は口を閉じた。
「逃がさない逃がさない逃がさない逃がさない逃がさな
い逃がさない逃がさない逃がさない逃がさない逃がさな
いぜぇ―――ったいにがさないんだからっ!」

    ☆   ☆   ☆

 そして日も暮れて、今日も楽しい(?)Python教室。
「今日の話題は辞書(dictionary)だよ」

※注意:「ディクショナリ」とカタカナ読みしている訳
 本もあります。

「電子辞書?」
「そういうモノを作るためにも確かに使えるけど、原始
的なデータベースみたいなものかな? 前回やったリス
トのインデックスが、数字以外でもオッケーって感じの
モノだよ」
「数字以外どういうこと?」
「つまり文字列とか。ま、ちょっと見てみてよ」

    >>> d = {"会長":"大鳥翔子","副会長":"天美修也"}
    >>> print d["会長"]
    大鳥翔子
    >>> print d["副会長"]
    天美修也
    >>> d["書記"] = "木崎未央"
    >>> print d["書記"]
    木崎未央
    >>> d["会計"] = "羽島八重"
    >>> d["会計"] = "朽縄巽"
    >>> print d["会計"]
    朽縄巽
    >>>

「珍しくずいぶんと判りやすい例ね」
 昼間に望美に非常識と言われたことが、ほんの少しだ
け堪えたらしい。
「リストとの違い、判った?」
 翔子は少し考える。
「そうね、まず、全体をブレース'{}'で囲むこと、イン
デックスと内容をコロン':'で区切って、それぞれの内容
を、リストみたいにカンマで区切って書くってとこ?」
 巽は頷く。
「そうだね。辞書ではインデックスのことをキー (key)
って呼んでる。あと、追加のところ、気づいた?」
 画面をもう一度見る翔子。
「そういえば、"書記"や"会計"は、書き換えじゃなくっ
て追加してるわね」
「そういうこと。キーが既にあれば、値の入れ替え。キー
が無ければ、キーと値を追加。数値によるインデックス
じゃないから順番もない。だから、リストよりファジー
に扱えるんだよ」
「そういえばさっき、『数値以外でも』って言ったわよ
ね。じゃ、数値をキーに出来るの?」
「出来るよ」

    >>> dn = {1: 100, 2: 200, 3: 300, 4: 400, 5: 500}
    >>> dn[6] = 600
    >>> dn
    {1: 100, 2: 200, 3: 300, 4: 400, 5: 500, 6: 600}
    >>>

「………考えてみたら、数値を使うならリストでいいわ
ね」
「そんなこと無いよ。ある数値と値を直結させたいなら
辞書をつかわなきゃいけない。リストのインデックスは、
順番を管理するだけのものだから、例えば途中を消した
らインデックスは変化しちゃう。それに、飛び飛びの数
値を扱うなら、やっぱり辞書を使ったほうが効率的だよ」
「リストの方を、キーが無い辞書、と考えた方がいいの?」
「どうなんだろう? 順序のほうが大切な時もあるしね。
文字列やリストのシーケンス (sequence) に対して、辞
書は写像 (mapping) っていう、別のものと考えた方がい
いかもしれないね」
「写像?」
「うん」
「あたしの記憶に間違いなければ、写像って関数のこと
じゃなかったっけ」
 翔子のツッコミに、巽の背中に脂汗が流れる。
「う………実はその通りなんだよね。辞書はキーに対し
て一対一対応で値を設定するけど、関数はアルゴリズム
で書けるっていうだけなんだよ」
「じゃ、辞書って要らないんじゃないの?」
「単なる参照ならともかく、キーや値の追加や変更まで
サポートしようとすると、面倒だと思うけど」
「それもそうね」
「データ型が豊富なのは確かに意味便利なんだけど、あ
まり多いとかえって覚えるのが大変だから、Python では
無闇に多くしないように調整してるんだ。その中でも、
拡張機能じゃなくってブレース括弧を使う専用の記法ま
である辞書は、よく使われるっていう証拠だよ」
「じゃ、別のデータ型が必要になったらどうするの?」
「前にもちょっと言ったけど、自分で作ればいいんだよ。
それも、今あるデータ型を拡張して新しい型をつくるこ
とも出来るから、作業はホントに必要最低限で済むんだ」
「どうやってやるの?」
 巽が首を振った。
「それは、用意されてるデータ型で対処しにくい作業に
ぶつかった時、考えればいいよ。データ型を作ることイ
コール・プログラミングっていう言語もあるけど、Python
はそうじゃないからね。それに、殆どの作業は基本的な
データ型で対処できるはずだよ」
「簡単だって言ったじゃない」
「簡単だよ。でも、意味ないところでやっても仕方ない」
 しかし翔子は、引き下がらなかった。
「意味なくとも、時には、知的好奇心に応えることも必
要だと思うわ」
 巽は、ふぅっとため息をついた。
「判った、降参降参。今回の辞書の話を最後までしたら、
辞書機能を少し拡張して、新しい型を作ってみよう」
「やたっ」
 多分、『後悔先に立たず』。
「ホントはクラスの話は、もう少し後の予定だったんだ
けどなぁ。まぁ、いっか。さて、辞書の機能、一通り説
明していくよ」

    >>> k = d.keys()
    >>> for x in k:
    ...  print x,
    ...
    会長 会計 書記 副会長
    >>>

「keysメソッドは、辞書のキーをリストとして返すんだ」
「なんで、会長の横が会計なの?」
「辞書の中は順不同だからね。登録した順番とか、あん
まり関係無いんだ」
「ふぅん」

    >>> v = d.values()
    >>> for x in v:
    ...  print x,
    ...
    大鳥翔子 朽縄巽 木崎未央 天美修也
    >>>

「valuesは逆に、値の方をリストとして返すんだ」
「ほらほら、やっぱり巽があたしんとこ、寄ってきてる」
「偶然だよ」
「そぉ? あたしにくっつきたいんじゃないの?」
「な、なんでそうなるんだよっ!」
 意表をつかれて、思わず赤面する巽。
「きしし」
 ちなみに、本当に偶然です(筆者)
「つ、次いくぞっ! 次っ!」

>>> i = d.items()
>>> for x in i:
...  print x[0],x[1]
...
会長 大鳥翔子
会計 朽縄巽
書記 木崎未央
副会長 天美修也
>>>

「ほらほらほら、やっぱりくっついてるぅ〜」
「やかましいっ! やっぱ、こういう例は使うもんじゃ
ないな。それにこれじゃ、何が起こってるかわかんない
し。新しい辞書、つくろう」
「え〜っ? 面白いのにぃ☆」
「うるさいうるさいっ!」

    >>> dh={
    ... 'KING ARTHUR':'Graham Chapman',
    ... 'SIR LAUNCELOT':'John Cleese',
    ... 'SIR GALAHAD':'Michael Palin',
    ... 'SIR ROBIN':'Eric Idle',
    ... 'SIR BEDEVERE':'Terry Jones'
    ... }
    >>> dh.keys()
    ['KING ARTHUR', 'SIR GALAHAD',
     'SIR LAUNCELOT', 'SIR ROBIN',
     'SIR BEDEVERE']
    >>> dh.values()
    ['Graham Chapman', 'Michael Palin',
    'John Cleese', 'Eric Idle', 'Terry Jones']
    >>> dh.items()
    [('KING ARTHUR', 'Graham Chapman'),
     ('SIR GALAHAD', 'Michael Palin'),
     ('SIR LAUNCELOT', 'John Cleese'),
     ('SIR ROBIN', 'Eric Idle'),
     ('SIR BEDEVERE', 'Terry Jones')]
    >>>

「うぁ、またわけわかんないネタ」
「いいのっ! Pythonの伝統なんだからっ!」
 困ったことに、本当に伝統なのである。
「それはそれとして、keys と values と items の動き、
わかった?」
「keys と values はともかく、items はなんなの、この
パーレン (丸カッコ) は?」
「タプル (tuple) っていうリストの一種だよ。ただし、
中身が変更できないんだ」
「中身が変更できないリストなんか、何に使えるのよ」
「いろいろ便利だよ。リストの内容が変更されると厄介
なのは前回やったけど、タプルは変更不可能だから、安
心して複数の値のセットを扱えるってこと」
「……………微妙ね。データ型は洗練されてるっていう
なら、もうちょっと利用方法があってもいいと思うんだ
けど」
「まぁ、いろいろあるんだよ。そうだね、例えば今やっ
てる辞書のキーは『不変オブジェクト』しか使えないん
だ。値のほうは何でもいいけどね。タプルは変更されな
い、即ち不変だから、辞書のキーに使えるんだよ」
「タプルがキー使えると、なんかいいことあるの?」
「こんなん、どう?」

    >>> dt = {}
    >>> dt[3, 4]=12
    >>> dt[5, 7]=35
    >>> print dt
    {(5, 7): 35, (3, 4): 12}
    >>>

「もしかして、座標?」
「それっぽいでしょ?」
「でもこれ、キーで書いたとき、括弧無いじゃない」
「括弧は省略できるんだよ。タプルの書き方にはちょっ
とクセがあって、基本的には括弧は必要無いんだ。その
代わりに、カンマが必要になる。ただし、要素が無いタ
プルだけは、カンマじゃなくて、パーレン括弧のペアだ
けで書くんだ」
「………よくわかんないわ」
「じゃ、とりあえず画面を見て」

    >>> ()
    ()
    >>> (1,)
    (1,)
    >>> 1,
    (1,)
    >>> 1, 2
    (1, 2)
    >>> 1, 2, 3
    (1, 2, 3)
    >>> (1)
    1
    >>>

「最後のは?」
「数値だよ。数字にそのまま括弧をかぶせても、数値と
してしか通用しない。空タプル以外は、カンマは絶対に
必要なんだ」
「とりあえずオッケ」
「少し面倒かな?」
「かなり、ね。そろそろティータイムかしら」
「うん、休憩しよう」
 本日のティーブレイクは、烏龍茶に包子。
「飲茶風?」
「そろそろ涼しくなってきたらか、いいでしょ、こんな
のも」「うん、美味しい」
「でもさ、辞書のキーに文字列使うのって、面倒くさく
ない?」
「そう?」
「うん。必ずクォーテーションかダブルクォーテーショ
ンで囲まなきゃいけないでしょ? それもどっちも半角
だし、さっきみたいに日本語をキーにしてたら、入力、
面倒じゃない?
「う〜ん、実際にデータベースとして使う時は、前やっ
た raw_input 入力関数みたいなのを使ったり、ファイル
から直接読み込んだりすることが多いから、必ずしもク
ォーテーションは必要無いんだ」
「ファイルから読み込む?」
「あ、そういえばファイルの話、してなかったね。Python
では、ファイルはシーケンスの一種として扱えるから、
結構手軽だよ。後半は、簡単なデータベース、作ってみ
ようか」
「へぇ? そんなに簡単に作れるの?」
「キーを入力したら、値を表示するだけのものだけど、
データ数が多ければ結構使えるよ」
「面白そうね」
「じゃ、早速………」
「まだお茶飲み終わってないじゃない。あわてないの」
「はい………」

# coding:shift_jis

f = file('meibo.txt','r')
d = {}

for i in f:
 k, v = i.split(",")
 d[k] = v

f.close()
key = "START"

while key:
 key = raw_input("検索キー:")
 if d.has_key(key):
  print "照合結果:", d[key]
 else:
  print "該当するデータはありませんでした\n"

「じゃ、再開。プログラムを db.py っていうファイルに
保存して、meibo.txt っていうファイルに、次のように
打ちこんでおくよ」

会長,大鳥翔子
副会長,天美修也
書記,木崎美央
会計,朽縄巽

「カンマは何?」
「カンマで値を区切ってるんだ。こうしておけば、表計
算ソフトなんかで読み込んだり、内容を編集したりでき
るんだ」
「四行ぐらい、メモ帳で十分じゃない」
「今はね。でも、大量のデータを扱うようになった時の
為に、こういうフォーマットは覚えておいて損は無いと
思うよ」
「そんなことには、ならないと思うけど………」
「どうせ何かで区切らなきゃならないからね」
「ま、そういうものなら」
「じゃ、動かしてみて。ファイルをダブルクリックすれ
ば、動くよ」

    検索キー:会長
    照合結果: 大鳥翔子

    検索キー:書記
    照合結果: 木崎美央

    検索キー:副会長
    照合結果: 天美修也

    検索キー:会計
    照合結果: 朽縄巽

    検索キー:書記長
    該当するデータはありませんでした

    検索キー:

「あ、結構面白い。ハマるかも」
「基本的にキーと値のペアだけだから、応用効きそうで
しょ?」
「そうね。で、終わるにはどうするの?」
「何も入れずにEnterキーを押せばいいよ」
 翔子が Enter キーを打つと、ウィンドウが瞬時に消え
る。
「あ、終わった」
「じゃ、内容解説ね。まず、file 関数はファイルを読み
込む関数で、第一引数に読み込むファイル名を、第二引
数に『オープンモード』を書くんだ。今回は読み出しモー
ド (read) だから、の'r'。他にも、書き込みモード
(write) の'w'や追加モード (add) の'a'なんかがあるけ
ど、詳しくはまたね。ちなみに今回みたいな読み出しだ
けなら、オープンモードは省略して、ファイル名だけで
もいいんだよ」
「じゃ、なぜ書いたの?」
「説明のため」
「やな感じね」
「すぐに書き出しもやるからね。ファイルの読み書きが
できれば、プログラムの利用範囲がぐんとひろがるよ」
「わかったわよ」
「じゃ、続き。for 文で f を使うと、ファイルの内容を
1行毎に切り取って変数に入れてくれるんだ。今回は i
だよね」
「便利ね」
「うん、最近の機能だよ。以前は readlines っていうメ
ソッドを使ってたんだ。で、次の split だけど、文字列
を指定した区切り文字で区切ってリストにして返してく
れるんだ」

    >>> s = "abc:def:ghi"
    >>> s.split(':')
    ['abc', 'def', 'ghi']
    >>>

「代入のとこで、なんかヘンなことしてるわね」
「鋭いっ! 気付いた? コレ、タプルなんだよ」
「だって括弧が………あ、省略できるんだっけ?」
「実は、最初の講義で、コレやったの覚えてる?」
「えっと(ノートをめくる)あ、ホントだ。2個の数値
を一気に代入するとか、変数を入れ替えるとか」
「そうそう。『タプルの展開』って言ってね、左辺にタ
プル、右辺に同じ要素数のシーケンス………リストやタ
プルなんかを置くと、それぞれ順番に、一気に代入して
くれるんだよ」

    >>> a, b, c = s.split(':')
    >>> a
    'abc'
    >>> b
    'def'
    >>> c
    'ghi'
    >>>

「さっきの簡易データベーススクリプトでは、i.split(',')
 の結果の要素はちょうど2個になるから、k と v にそ
 れぞれ代入されたんだよ」
「う〜んと………ちょ、ちょっとわかりにくいカモ」
「じゃ今の例で、中身を一度展開してみるね」
 巽は白紙に、次のように書いた。

    s.split(':')⇒['abc', 'def', 'ghi']

    a, b, c = ['abc', 'def', 'ghi']

    'abc' ⇒ a
    'def' ⇒ b
    'ghi' ⇒ c


「s.split(':') の結果が ['abc', 'def', 'ghi'] にな
って、左辺の a, b, c と同じ要素数になるから、一つず
つ順番に入るんだよ」
「ふむ、了解」
「関数は右辺で評価されて………計算されて、答えと置
き換えられるって言ったほうがいいかな………そして左
辺の変数に代入される。その時左辺がタプルやリストみ
たいなシーケンスであれば、左辺と右辺の両方が展開さ
れて、それぞれに入るんだよ」
「左辺と右辺の両方の要素数が違ったら?」
「エラーになる」
「あらら、シンプルね」
「うん。この方法は、結果をちゃんと意識してしか出来
ないんだ。でないと、結果が見えにくくなるからね」
「ところで気になるんだけど、シーケンスって、確か文
字列もシーケンスよね」
「うん」
「文字列も展開できるの?」
「できるよ」

    >>> a, b, c = "xyz"
    >>> a
    'x'
    >>> b
    'y'
    >>> c
    'z'
    >>>

「じゃ、左辺に書いたら?」
「文字列は不変オブジェクトだから、ダメだよ。第一、
変数を要素に出来ないし」
「あれ? タプルも不変じゃないの?」
「要素の入れ替えは出来ないけど、可変オブジェクトを
入れることは出来るから、入ってる要素が変化すること
はあるよ」

>>> t = ({}, {}, {})
>>> t[0][0] = 5
>>> t
({0: 5}, {}, {})
>>>

「?? な〜んか、だまされているような気が」
「気のせいだよ」
 実は、気のせいではない(後述)
「さて、漸く次だ。while や if の判定式について、説
明が必要だね。Python では、不等式や等式の結果の真
(True) や偽 (False) みたいな真偽値…ブール値って言
うんだけど…の他に、次のものを偽とする、っていう決
まりがあるんだ」

    <偽>と判定されるもの
    ブール値の偽      False
    数値のゼロ
        整数      0
        ロング整数   0L
        浮動小数点数  0.0
        虚数      0j
        複素数     (0+0j),(0.0+0.0j)
    要素をもたないコレクション
        空リスト    []
        空タプル    ()
        空文字列    '',""
        空辞書     {}
        空集合     set([])
    Noneオブジェクト    None

「逆に言えば、上のもの以外は、全て真と判定されるん
だよ」
「じゃ、ゼロしか入ってないリストとかは、偽?」
「真だよ。要素が入ってるリストは、たとえその要素が
偽でも真になるんだ。リストが偽になるのは、空リスト
の時だけだよ」
「ややこしいのね」
「慣れるまでは、確かにね。使ってるうちに、なんとな
くわかるようになるけどね。ともかくここでは、while
ループで空文字列を検出するようにしてるんだ。入力し
た文字列は変数 key の中に入るから、key が空文字列な
ら、while ループは終了する、ってこと」
「空文字列って、文字入力せずにEnter押した、アレ?」
「そういうこと」
「聞いて見れば、随分簡単な仕掛けね」
「手品もプログラムも、似たようなもんだからね」
「まぁ、見えないトコでこそこそとやるのは似てるかも」

    それはちょっとヤな言い方だ

「つ、次いくよ。辞書の has_key メソッドは、その名の
通り『キーを持ってるか?』って辞書に聞くメソッドな
んだ。引数で指定したキーがあれば True を、無ければ
False を返す」
「で、キーがあることを確認したら、キーの値を表示、
無ければ『該当するデータはありませんでした<改行>』
ね」
「よくできました」
「ところで、値があるかどうか調べるメソッドってある
の?」「いや、別に無いよ。どうしても調べたければ

    >>> value in dict.values()

って書けばいいことだし」
「inって、for以外にも使えるの?」
「うん。この場合は演算子の一種かな。シーケンスの中
に特定の要素があるかどうかを調べる時に使うんだ」
「でも、その理屈だと、has_keyが無くても

    >>> key in dict.keys()

でもいいんじゃない?」
「キーの検索はよく使うから、メソッドになってるんじ
ゃないかな」
「そういえば、データ型を拡張するとかいう話、どうし
たのよ?」
「忘れてた………。でも、このままでもデータ型って結
構便利だから、使えそうな拡張は難しいよ」
「使えなくてもいいじゃない。勉強用でしょ? has_value
ってのが入ってる新しい辞書、作ろうよ」
「………さっきのリベンジ?」
「んふふ」
「はいはい。ほんじゃ、新しい辞書を実装してみますか」

    >>> class NewDict(dict):
    ...  def has_value(self,v):
    ...   if v in self.values():
    ...    return True
    ...   else:
    ...    return False
    ...
    >>> nd = NewDict([])
    >>> nd
    {}
    >>> nd[5]=500
    >>> nd
    {5: 500}
    >>> nd.has_key(5)
    True
    >>> nd.has_value(500)
    True
    >>>

「うぁ………いきなり、わかんない………」
「だから言ったじゃないか、後にしようって」
「だって、簡単って言ったじゃないっ!」
「簡単だよ。実質 class のブロックの部分だけだからね。
どうする? 一応説明聞く? それともやめとく?」
「い、一応、聞くだけ………」
「オッケー。まず、dict の説明からね。関数としては、
dict はこんな感じに使うんだ」

    >>> d = dict([
    ... ('KING ARTHUR','Graham Chapman'),
    ... ('SIR LAUNCELOT','John Cleese'),
    ... ('SIR GALAHAD','Michael Palin'),
    ... ('SIR ROBIN','Eric Idle'),
    ... ('SIR BEDEVERE','Terry Jones')
    ... ])
    >>> d
    {'KING ARTHUR': 'Graham Chapman',
     'SIR GALAHAD': 'Michael Palin',
     'SIR LAUNCELOT': 'John Cleese',
     'SIR ROBIN': 'Eric Idle',
     'SIR BEDEVERE': 'Terry Jones'}
    >>>

「なんかややこしいわね………タプルのペアのリスト?」
「そう、シーケンスのペアのシーケンスを引数として受
け取って、辞書にする効果があるんだ」
「ややこしい関数ね。まぁ、なんとなく使い方はわかる
けど」
「ところがこの dict、関数と全く同じ形式で使えるんだ
けど、実は関数じゃないんだな」
「なによそれ?」
「分類としては、『クラス』になるんだ。つまり、デー
タ型の雛型」
「わけわかんない」
「実は言わなかったけど、今日一つ、そういうクラスを
使ってるんだ」
「何よ?」
「file」
「え?」
「file だよ。file は実は、関数じゃなくってクラスだ
ったんだよ。クラスによって作られたオブジェクトのこ
とをインスタンスって言うんだけど、簡易データベース
スクリプトで使った f は file クラスのインスタンスな
んだ」
「うぁー、ちょ、ちょっとタンマっ! 頭ウニっ!」
「はいはい」
「深呼吸、深呼吸。はぁはぁすぅすぅ」
「……………」
「……………はい、つづけて」
「はいはい。クラスとインスタンスの関係ってのは、実
は意外と簡単で、たとえば1は整数クラスのインスタン
スなんだよ」
「クラスっていうのは型なの?」
「まぁ、そういうこと」
「じゃ、型って言えばいいのに」
「そういうわけにもいかないんだよね。さっき出てきた
ように class は文法用語だし、instance も、isinstance
メソッドみたいなトコロに、名前出てくるからね」
「つまり、クラスは型で、インスタンスはその型の値ね」
「そうそう」
「じゃ、覚えた。で、辞書ってのは、実際には dict ク
ラスのインスタンスなのね」
「うん」
「もしかして、今までやった、整数とか浮動小数点数と
か文字列とかリストとかタプルとか、みんなクラスある
の?」
「あるよ。整数は int クラス、浮動小数点数は float
クラス、文字列は str クラス、リストは list クラス、
タプルは tuple クラスだよ」
「要するに、言い換えね」
「ま、そう思っていいよ。厄介なのは、クラス自身、型
でもあり、一種の値でもあるんだ。だから、プログラム
の中で扱う時には、正確には、『クラスオブジェクト』
って言うんだ」
「型なのに値なの?」
「うん。だって、リストの中にストックとか出来るし…」

    >>> classlist = [int, float, str, list, tuple]
    >>>

「………それ、もう慣れた」
「C++ か Java あたりをやってる人には、引きつけ起こ
すほどショックなんだけどなぁ」
「あたし、『しーぷらぷら』や『ぢゃば』なんて、知ら
ないモン」
「ま、いいや。そういうモノだと思って。今日は本来、
クラスの話をする予定じゃなかったから、クラスは型だ
ってことと、その型の値のことをインスタンスって言う
ってことだけ判ればいいよ」
「忘れそうだなぁ」
「忘れたらノート見ればいいよ。それに今日の重要ポイ
ントは、クラスじゃなくって辞書だからね」
「辞書も忘れそう」
「それは困る」
「困る?」
「困るよ」
「ホントに困る?」
「ホントに困るよっ!」
 翔子は、にっこり笑った。
「じゃ、覚えたげる」

    ☆   ☆   ☆

 巽や翔子が住む天鳳町(てんぽうちょう)は、古い集
落の近くの山を切り開いて作られた新興住宅地だ。
 そのため、いわゆる『雛壇』型と呼ばれる団地になっ
ていて、やたらと坂が多い。
 巽と翔子は、待ち合わせするわけではないが登校時間
はほぼ同じなので、結果的には二人で一緒に通っている
ような格好になる。
 ところがなぜか、今日は三人だった。
「坂下ちゃん、ご近所だったのね」
 なんだか巽を異様な目で見る望美に少したじろきなが
らも、声をかける翔子。
「ええ、住所録から調べました。今日より、毎日ご一緒
させていただきます」
 巽は望美の様子に全然気付かずに、ツッコミを入れる。
「住所録って、確か今は『個人情報の保護に関する法律』
とかで、厳重管理されてるんじゃ………」
 望美はにっこり嗤った。
 鈍い巽でさえ、思わず背筋が凍りつくような壮絶な笑
みだった。
「あたしは報道局員だよ。そんなの、どうにでもなるわ。
もっとプライベートなことだって知ってるよ」
「そ、それって完全なルール違反なんじゃ………」
「第五十条雑則の適応除外だもん」
 『個人情報の保護に関する法律』第五十条は報道関係
者について、この法律の適用範囲外と定めている。
「で、でも、それって社会批判とか公正に行うためじゃ
………」
「社会正義のためよ」
「社会正義?」
「そう、朽縄巽という非常識人間を真人間に公正させる
という目的のためだよ」
 翔子は、がしっっと望美の両手をつかんだ。
「坂下ちゃん、わかってくれたのね」
「はい。この世間ズレ男には最調教が必要です」
「うんうん、あたしが十数年かかって出来なかったこと、
あなたの協力があれば、出来そうよ」
「ええ、一緒にこのダメ人間を更正させましょう」
「坂下ちゃんっ!」
「大鳥せんぱいっ!」
 目を潤ませながら手を取り合う二人を、巽は呆然とし
ながら見るしかなかった。

 昼休み、執行部室にて。
「へぇ、坂下くんがね………」
 天美が面白そうに言う。
「いいでしょ、理解者が出来て、あたしも嬉しいわ」
「冗談じゃないですよ全く」
 巽が死にそうな声を上げる。
「教室だけが、唯一翔子の説教から逃れられる場所だっ
たのに、これで四六時中気の休まる暇、ありませんよ」
 天美は、巽のそばに行ってぽん、と肩を叩いた。
「ま、結局は坂下くんが朽縄くんにそれだけ入れ込んで
るってことだからね。男冥利に尽きると思いなよ」
「「え? そうな(んですか|なの)?」」
 巽と翔子が、同時に言う。
「そういうこと」
 ふと翔子の方を見ると、なにやらぶつぶつと呟いてい
る。
「どうしたの?」
「犬に惚れるなんて………坂下ちゃん、ヘンタイだった
のね」「………」
 どう突っ込めばいいのかわからない妙な雰囲気の中へ、
美央が入ってきた。
 前後のつながりを知らない美央には、その妙な沈黙の
わけが、当然全くわからなかった。
「どうしたんですか」
 翔子は、すばやく美央の両手を取ってこう言った。
「ヘンタイはダメよ、木崎ちゃん」
「はぁ?」
 いや、多分手遅れだろう。





<翔子のノート(ロンより翔子?)>
Lesson.6
    辞書(dictionary):キーで検索できるコレクション

    書き方
        {キー: 値, キー: 値, キー: 値 ...}
        キーは、数値、文字列、タプルなど不
        変オブジェクト
        値は何でも良い
    キーによる代入
        dict[キー] = 値
        リストと異なり、存在しないキーへの
        代入により、エントリ (アイテム) が
        自動的に増える
    keysメソッド
        dict.keys() ⇒ キーのリスト
    valuesメソッド
        dict.values() ⇒ 値のリスト
    itemsメソッド
        dict.items() ⇒ 「キーと値のタプル」のリスト
    has_keyメソッド
        dict.has_key('キー')
        キーがあれば、Trueを返す
    dictクラスオブジェクトの使い方(コンストラクタ)
        dict([[キー, 値], [キー, 値], [キー, 値]]) ⇒ 辞書
        dict(((キー, 値), (キー, 値), (キー, 値))) ⇒ 辞書
        dict(辞書) ⇒ 辞書

    タプル(tuple):要素不変なリスト

    書き方:括弧ではなく、カンマが重要
        要素, 要素, 要素
        (要素, 要素, 要素)
        (要素,)

    ファイルオブジェクト:システムのファイルをラ
    ッピング
        f = file('filename') : 読み出しモードでオープン
        f = file('filename','r') : 読み出しモードでオープン
        f = file('filename','w') : 書き込みモードでオープン
        f = file('filename','a') : 追記モードでオープン

    splitメソッド(文字列):文字列を分割しリスト化
        str.split('区切り文字')
        区切り文字を省略すると、ホワイトスペース・タブ等で分割

    <偽>と判定されるもの
    ブール値の偽      False
    数値のゼロ
        整数      0
        ロング整数   0L
        浮動小数点数  0.0
        虚数      0j
        複素数     (0+0j),(0.0+0.0j)
    要素をもたないコレクション
        空リスト    []
        空タプル    ()
        空文字列    '',""
        空辞書     {}
        空集合     set([])
    Noneオブジェクト    None


<巽の薀蓄(未使用)>

<<<辞書について>>>

 AWK や Perl では連想配列 (associative array)、
SNOBOL4 では連想記憶 (associated memory) と呼ばれて
いる。この方式を最初に取り入れたのは SNOBOL4 であり、
スクリプト言語の存在を世に知らしめた AWK が取り入れ、
Perl は AWK から継承した。
 なお、AWK では、コレクションは連想配列だけである
が、Perl では他にも様々なコレクションがある。


<<<代入子とシンボルについて>>>
 代入子'='の左辺と右辺は、実は全く別物である。
 例えば、

    a = b

と書かれていたとすると、この a と b の意味合いは全
く異なる。
 a は値に結び付けられる『シンボル』としてそのまま
使用されるが、b は『変数 b の値』に置き換えられる。
 つまり、b が 100 であれば 100、'Nudge! Nudge!'な
ら'Nudge! Nudge!'に置き換えられてしまい、実質的には

    a = 'Nudge! Nudge!'

と同じ意味となる。
 なおこのとき、a の中身があれば、a とは縁が切れて
しまう。
 ところで、本編で扱った『タプルの展開』だが、左辺
を右辺のタプルは勿論意味合いが違うので、素直に『特
殊な文法』と理解した方が良い。
 また、キーやインデックスによるコレクションの要素
指定も、考え出すと文法の中に隠れている参照的な意味
合いを考えなければならなくなるので、『そういうのに
こだわりたい』方以外は、考えない方が良いだろう。
 結論、『藪をつついて蛇を出すな。蛇の蒲焼が食いた
いのでなければ』

<後記>
 今回より、すこしフォーマットを変更してみました。
あくまで本編は入門者用ということで、難しい概念は極
力避けますが(ストーリーの展開上、ワザと入れてると
こはありますが)、どうしても進行に合わせて言ってお
きたいことが若干出てきたので、<巽の薀蓄(未使用)
>として収録しました。無理に理解する必要の無い概念
や、マメ知識的なことを書きますので、マイペースで見
てください。