PはPythonのP ---P IS FOR PYTHON--- 05h
"Bring out your dead! Ninepence."
『死体引き取りぃ〜 9ペンス』
by"MONTY PYTHON AND THE HOLY GRAIL"
0000-0101.パワー・リストの破壊力
最初は、好奇心だった。
恋愛するって、どんなのかなぁって。
男の子はあたしと違って、どんなこと考えるんだろう
か、って。
でも、なんだか直ぐ飽きてきちゃった。
適当に手近な子を選んだのが、まずかったのかな?
初めはドキドキしたけど、すぐに面白くなくなった。
話題も合わないし、感覚も合わない。
なにより、相手に興味が湧かなくなった。
だから、すぐに別れちゃった。
相手も全然、未練なかったみたいで、すぐに別の子と
付き合ってて、そっちは結構続いてるらしい。
だから、決めたんだ。
今度恋愛するときは、ちゃんと興味を持てる相手を選
ぼうって。
絶対に、楽しんでやるんだって。
相手のことが、知りたくて知りたくてたまらないなら、
多分ずっと、ドキドキしていられるはず。
そして、探してたものが、見つかるはず。
☆ ☆ ☆
朽縄巽は、今組んだスクリプト (プログラムのこと)
をざっと見渡した。
特に問題は無さそうに見える。
作っておいたダミーデータを読み込ませ、実行。
四つのファイルが、瞬時に出来上がる。
一つ目は、打ち込んだデータをそのまま XML 形式に書
き換えた保存データ。
二つ目は、それを処理し、簡単な統計データとしてま
とめたもの。
三つ目は、二つ目のファイルを Excel などに読み込ま
せて処理するための CSV という形式のテキストファイル
に変換したもの。
最後の一つは、HTML に張り込むためのテーブルデータ。
巽は、全てのファイルをチェックし、自分の思った通
りに出来ていることを確認した。
「出来たよ」
「ありがとー、朽縄くん。いやぁ、助かった助かった」
大袈裟に感謝しているのは、同じクラスの坂下望美
(さかした のぞみ)だ。
黒いフレームのトンボ眼鏡を愛用しているので、ぱっ
と見はなんだか漫画のキャラみたいに見えないこともな
いが、よく見れば、くるくるとよく変化する表情が魅力
的な可愛らしい女の子だ。
「ごめんね朽縄くん、余計なことさせちゃって」
成り行き上、巽に仕事を持ってくることになった木崎
美央は、なんだか恐縮している。
「構わないよ、別に手間でも何でもなかったから」
別に謙遜でもなく普通に言う巽の背中を、、望美が喜
んでばんばんと叩く。
「いやぁ、さすが5組のハッカー殿は言うこと違うねぇ。
あたしらには、ぜ〜んぜん、ちんぷんかんぷんのこと、
こともなげにやっちゃうんだからね」
「ハッカーって呼ぶのはやめてよ」
巽は、珍しく不快を露に言い放つ。
「なんで? だって確か、プログラマの優秀な人のこと
でしょ? 犯罪者のほうはクラッカー、で、良かったよ
ね」
コンピュータには詳しくなくとも、流石はプチジャー
ナリストだけあって、横文字語には詳しいようだ。
望美は自治会機関の一部、報道局の新聞部の一員である。
しかし、コンピュータヲタのこだわりまでは、当然だ
が理解していない。
「僕程度の人間が、ハッカーって呼ばれるのは、烏滸が
ましい (おこがましい) って言ってるんだよ。彼らは僕
の目標だからね」
「またまた、謙遜しちゃって」
「もし次に言ったら、二度と仕事しない」
「………う〜、わかったわよ。ノリ悪いなぁ。そりゃぁ、
報道局は執行部批判してるからあんまり印象良く無いか
もしれないけど、そんな言い方しないでもいいじゃない」
拗ねたように言う望美に、巽は首を振る。
「別に執行部に義理は無いよ。僕は仕事を押し付けられ
てるだけだからね。だけど、ハッカーの称号を冒涜する
ようなことは許さない。坂下だって、報道者の誇りはあ
るだろ?」
「あ、そういうこと」
にやっ、っと笑う、望美。
「職人のプライドってヤツね。OK、そんなら理解できる
わ。ごめんね」
巽はすぐに表情を和らげた。
「こういう仕事なら、いつでも呼んでよ。喜んで手伝わ
せてもらうからさ」
「ありがと」
なんだか妙な成り行きと雰囲気に、美央はあわてて釘
を刺そうとする。
「あ、あ、でも、執行部も結構、仕事あるし、朽縄くん、
会計だから特に………」
自治会などで一緒して最近仲良くなった望美の頼みで、
アンケート処理のシステムを作るために巽を紹介したの
は美央である。
その責任を自覚しての言葉なのだが、普段は大人しい
美央の態度の豹変に、望美は何か『それ以上』のものを
感じ、少しからかってみたくなった。
「わかってるわよ、美央。別に朽縄くんを取ったりしな
いってば」
「と、取るって………べ、別にあたしのモノじゃ………」
「なに言ってるのよ。執行部から、よ」
望美の引っ掛けにまんまと嵌った美央は、盛大に自爆
して沈黙。
「ん、でも、コレだけ優秀なら、来期は自治会じゃなく
って、報道局で働いてくれると嬉しいけどね」
流し目をしてウィンクする望美に、勘違いの自爆で真
っ赤になっていた美央が、即座に復活して反応する。
「だめだめだめっ! 朽縄くんは執行部の、大鳥先輩の
モノなんだからっ!」
ちょ、ちょっと待ってよ
巽が突っ込みを入れる前に、望美が顔をしかめる。
「大鳥会長? 朽縄くんって、大鳥会長の年下のカレシ
なの?」
「そ、そうじゃないけど…………え、えっと、たしか、
犬だって………」
をい………
もう混乱して、何言ってるんだか判らない美央は、問
題発言を連発する。
「木崎、ちょっと黙って」
「だ、だってだって、えっと、その………」
巽は落ち着かせるように、美央の両肩に手を置く。
美央は別の意味で真っ赤になって、口を閉じた。
「坂下は木崎の友達かもしれないけど、執行部を批判す
る立場にある局の人間だよ。翔子の立場を不利にするよ
うな言葉は、控えないと」
その言葉に、早速食らいつく望美。
「へぇ、朽縄くん。大鳥会長のこと、名前で呼び捨てな
んだ」
「幼なじみだからね。姉弟みたいなもんだよ」
「そ、そうなの………」
しかしあっさり返す巽に、肩透かしを食らう。
「そういうこと。だから世話にもなってるし、執行部で
手伝えと言われれば、断れないってわけ」
「で、でも、だからって特別な関係に無いってわけじゃ
………」
ふぅ、っと大きなため息をつく巽。
「そうだなぁ、翔子も、男とか出来れば、少しは落ち着
くかもしれないなぁ。だれか翔子の世話したがるような
物好き、紹介してやってくれないか? そしたら僕も、
少しは楽になるかもね」
こりゃダメだ、とばかりに、望美が美央の方を振り向
くと、なにやら複雑な表情で巽を見つめている美央がい
た。
あ、こっちはまだイジりがい、あるかな?
「じゃ、朽縄くんって、今フリーなの?」
「木崎の言葉を借りれば、執行部のイヌ (所持品) だそ
うです」
冗談にしても、物悲しい科白である。
「そうじゃなくって、つきあってる女の子とか、いない
の?」
「需要も縁も無いので」
「変な言い方ね」
「翔子に言わせれば、だからモテないのだと」
「ふぅん。じゃぁ、練習も兼ねて、あたしと付き合って
みる?」
美央が、酸欠に喘ぐ魚のように目を剥いて口をパクパ
クさせて何か言おうとしているが、あまりのことに何も
言えない状態になっている。
「坂下さん、付き合ってる人、いないの?」
意外そうに言う巽。
「今んとこ、あたしもフリーよ。中学のときの彼氏とは
もうとっくに切れてる。高校も落ち着いたってコトで、
ちょっと新しいタイプと付き合ってみたいと思ってたト
コなんだ。朽縄くん、面白そうだし」
巽は、じっっ、と望美を見つめた。
途端、いままで完全に余裕で喋っていた望美が、まる
で心臓を鷲掴みされたように息苦しくなった。
そして、巽が、柔らかに笑った。
望美の心臓が、どくんっ、っと音を立てて撥ねる。
「冗談でも、ありがと。じゃ、執行部の方、顔出さない
といけないからね。木崎、行くよ」
「え? あ、は、はいっ!」
「あ、あ………」
美央を連れて出て行った巽に、望美は全く声がかけら
れなかった。
しばらく呆然としていた望美は、やがてぽつんと呟く。
「やば………これ、まじかも………」
☆ ☆ ☆
夜―――――翔子の部屋にて、いつものPython教室。
「今回からしばらく、コレクションの話をするね」
「コレクション? 切手?」
「違う」
「コイン?」
「違うって」
「ま、まさか、口に出せないようないかがわしいモノを
………巽くんフケツ☆」
なぜそうなる?
「………ワザと言ってる?」
睨む巽に、ケタケタと笑う翔子。
「あはは。で、何よコレクションって」
「…複数の値をまとめて扱う入れ物だよ。今までの変数
は一個の値しか収納できなかったけど、コレクションは
複数の値を収納できるんだ」
「文字列とかも、そうじゃないの? 複数の文字入れて
るでしょ?」
「鋭いね」
普通は気付かない
「その通り、文字列も実はコレクションの一種だよ。た
だ、その要素(中身)は文字だけしか入れられなかった
し、中身を変更も出来なかったからね。今日話す『リス
ト』は、そういった制限が無いんだ」
「変更不可能って………足し算とか掛け算とか、あと、
文字の取り出しとかしてたじゃない」
「あれは、文字列を使って新しい文字列を作ってただけ
だよ。元の文字列は、変化してない。他のプログラミン
グ言語では、文字列は変更可能っていうことが多いんだ
けど、Python では変更不可能になってるんだ」
「不便なのね」
出来ないことがあると、出来ないだけで不便だと思っ
てしまうのは、人間の大いなる錯覚の一つである。
何に使うのか判らない場合は、特に。
その錯覚が逆方向にエスカレートすると、買い換える
まで一度も使わない機能満載の携帯電話(古くはワープ
ロ専用機。若しくは、ビジネス用巨大パッケージウェア)
が出来上がる。
「新しい文字列が簡単に作れるんだから、問題無いと思
うけど? もし変数に入れてるなら、新しい文字列で入
れ替えればいいことだし」
「変更出来ないのには、なんか理由があるの?」
難しい質問だ
「う〜ん、文字ってそもそも、意識的に代入して変更し
ないかぎり、一部を変更させる必要ってあんまり無いん
だよね。むしろ判りにくくなるから、変更できないよう
にしたほうが良いと思ったんだろうね」
「じゃ、他の言語だと、どうして出来るの?」
「歴史的な理由や処理効率の関係なんだけど、長くなる
から今聞かない方がいいと思うよ」
ホントに長くなります
「それは警告ね?」
「いや、お願い。僕としては聞かれたことは答えたいん
だけど、多分、時間を潰すだけで理解するのは難しいと
思うから」
なんせ、『C 言語学習のバミューダトライアン
グル』の異名を取るポインタの話だ
「では、汝の願い、聞き届けよう」
「はいはい女神さま。で、リストの話だけどね………」
「………スルーしたわね」
「っていうか、今日の翔子、ハイすぎ」
「う、いいじゃない、たまには」
「いいけど、僕までテンション上げられないからね」
百万倍のハイテンション(by メガレンジャー)
「けち」
「じゃ、リストの話」
巽も逞しくなったものである。
「リストは、変数に入れられるものなら、何でも入れら
れる便利な入れ物なんだよ」
>>> l = [123, 4.5, 'aiueo']
>>> l
[123, 4.5, 'aiueo']
>>> l[0]
123
>>> l[1]
4.5
>>> l[2]
'aiueo'
>>>
「リストを作る時は、ブラケット'[]'で囲んで、要素を
列挙するだけでいいんだ。簡単でしょ」
「内容が違うだけで、文字列と同じね」
「いやいや、ここからが本領発揮」
>>> l[1]
4.5
>>> l[1] = 4.25
>>> l
[123, 4.25, 'aiueo']
>>>
「インデックス (添え字) で指定して代入ってのは、確
かに無かったわね。でも、これって、スライスでも書け
るんじゃない?」
よく覚えてたね翔子さん
「そうだね。じゃ、やってみてよ」
「えっと………」
>>> l = l[:1] + 4.25 + l[-1:]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: can only concatenate list (not "float") to list
「あ、なんか文句言ってる。もしかしてリストって、'+
'は使えないの?」
「使えるよ。ただ、'+'で連結できるのは、リストだけだ
からね。『浮動小数点数はダメだ』っていうエラーメッ
セージだよ」
ちなみに巽の英語の成績は、十段階評価の2〜3であ
る。
「どうすればいいの?」
「4.25をブラケットで囲めばいいんだよ」
「一個なんだけど?」
「無問題」
>>> l = l[:1] + [4.25] + l[-1:]
>>> l
[123, 4.25, 'aiueo']
>>>
「出来た」
「というわけ」
「これなら、インデックスで代入できなくても………っ
て、明らかに面倒よね。文字でも出来ればいいのに」
「文字列操作は、他にも色々できるよ。ただ、今日はと
りあえず、リストの話を続けさせてよ」
「はいはい」
「じゃ、次いこう次。あんまり使わないけど、変数を消
す del っていう文法があるんだ。前に一回、ちょっとだ
け使ったけどね」
>>> a = 100
>>> a
100
>>> del a
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in ?
NameError: name 'a' is not defined
>>>
「いかにも意味なさそうな文法ね」
ガーベッジコレクション完備だと、特に
「ところがコレ、リストだと意外と役に立つんだよね」
>>> l = [0,1,2,3,4]
>>> del l[2]
>>> l
[0, 1, 3, 4]
>>>
「インデックスで指定したものだけを消すってわけね」
「便利でしょ」
「便利っていうか………スライスでも出来るけど、簡単
ってトコよね」
「一応スライスよりは、メモリの消費が少ないし、動作
も速いよ。一回やるだけなら殆どわかんない程度だけど、
何度も繰り返すと、やっぱり若干は影響してくるからね。
さっきのインデックスによる挿入でも同じだけどね」
「なんでスライスより早いの?」
「スライス連結は、新しいリストを作って代入するから
ね。インデックスによる操作は、リスト自体を変化させ
るから早いんだよ」
「つまり、インデックスによる操作って、便利だって言
いたいのね」
「そう………とも言い切れないんだよね」
煮え切らないヤツである
「ちょっとコレ見てくれる?」
>>> x = 100
>>> y = x
>>> x = 200
>>> print y
100
>>>
「えっと、x に 100 を代入して、y に x の値の 100 を
入れて、で、x に 200 を代入しなおして、y の中身を表
示したら……… 100 に決まってるわよね。これが何?」
いや、結構ややこしいと思うが
「その通り。じゃ、こっちを見て」
>>> x = [0, 1, 2, 3, 4]
>>> y = x
>>> x[2] = 200
>>> print y
[0, 1, 200, 3, 4]
>>>
「えっと、x にリストを代入して、yにxのリストを代
入して、x のリストを変更したら………あ、あれ? な
んで y の内容が変わるの?」
「そういうこと。インデックスによる代入は、リスト自
体を変更するんだ」
「どういうこと?」
「当たり前の話だけど、整数の 100 は不変だよね。100
と書いて 200 になったら大変だから」
「当然でしょ」
当然だ
「でも、リストは、内容を変更できるモノなんだ。で、
y = x は確かに代入なんだけど、代入って正確には『名札
をつける』って言ったよね。だから、実際、こんな風に
なってるんだ
[x]→[リスト]←[y]
つまり、x という名札がついてるリストに、もう一個 y
という名札をつけた状態なんだ。だから、x の名札を辿
って変更したリストは、実は y のリストと同じモノなん
だ」
「もしかして………文字列が不変なのって?」
「それもあると思うよ。特殊な方法を使えば、文字列を
可変にすることは可能なんだけど、そういう特殊な手段
をとらない限り、変更できないんだ」
「同じ内容の、違うリストをコピーして渡すこと、出来
ないの?」
「できるよ。スライスを使うんだ」
>>> x = [0, 1, 2, 3, 4]
>>> y = x[:]
>>> x[2]=200
>>> print y
[0, 1, 2, 3, 4]
>>>
「なんか変な指定してるけど?」
「うん、スライスで'[:]'を指定すると、同じ内容のコピー
を新しく作って渡すんだ。でも別物だから、片方を変更
しても大丈夫だよ」
「なるほど、これでいいのね」
「……………」
「な、なによ、いきなり黙って」
「とりあえずは」
「………って、なんかまだ不都合、あるのね」
そろそろ慣れた翔子さん
「そういうこと。でもその説明の前にやることがあるか
らね」
「はいはい、じゃ、聞きましょう」
「さっき、リストって『何でも』入れられるって言った
よね」
「言ったわね」
「実は、リストの中にリストも入れられるんだ」
>>> x = [0, 2, [3, 4], 5]
>>>
「器用ね。ところで、中の 3 とか使いたいとき、インデ
ックスどう書くの?」
「うん、こんな感じかな」
>>> x = [0, 2, [3, 4], 5]
>>> x[2]
[3, 4]
>>> x[2][0]
3
>>>
「あ、これ判る。説明させて」
「どうぞ」
「えっと、x[2] が [3, 4] だから、x[2] を仮に x2 と
すると、x2[0] が 3 になるってことよね。だから x[2][0]
が 3 と」
一目でこれがわかれば、大したものである
「まぁ、間違ってないけど、(x[2])[0] のほうがシンプ
ルじゃない?」
それ、初心者に求めるか?
「………わ、わかりにくいわ。あたしの方が簡単よ」動
揺が声に出てますよ、翔子さん(無理ないけど)
「別に理解できれば、なんでもいいや」
それで済ますのか、お前は
「で、問題はここからなんだな」
>>> x = [0, 2, [3, 4], 5]
>>> x[2][0]
3
>>> y = x[:]
>>> x[2][0] = 300
>>> print y
[0, 2, [300, 4], 5]
>>>
「………な、なんで? さっき 、 スライスはコピーする
って言ったじゃない」
「その通り。だから、今の続けて書くと………」
>>> x[0] = 1000
>>> print y
[0, 2, [300, 4], 5]
>>> print x
[1000, 2, [300, 4], 5]
>>>
「どういうこと? リストの中だけ変わるなんて」
「スライスがどういうことをしてたかを、1行づつ書い
てみるよ」
>>> x = [0, 1, 2, [3, 4], 5]
>>> y = [0, 0, 0, 0, 0]
>>> y[0] = x[0]
>>> y[1] = x[1]
>>> y[2] = x[2]
>>> y[3] = x[3]
>>> y[4] = x[4]
>>> y
[0, 1, 2, [3, 4], 5]
>>> x[0] = 1000
>>> y
[0, 1, 2, [3, 4], 5]
>>> x[3][0] = 300
>>> y
[0, 1, 2, [300, 4], 5]
>>>
「なんとなく………わかった。x[0] は数値だけど、x[3]
はリストだから、一個ずつコピーしても結局最初と同じ
ってことなのね」
「そういうこと。表面一列は別物に出来ても、結局リス
トがあるとその中は共有なんだよね」
「で、その対策、あるんでしょ?」
ある方面での学習は、着実にできつつある
「あるよ、多少面倒だけどね」
>>> from copy import deepcopy
>>> x = [0,1,2,[3,4],5]
>>> y = deepcopy(x)
>>> y
[0, 1, 2, [3, 4], 5]
>>> x[3][0]=1000
>>> y
[0, 1, 2, [3, 4], 5]
>>>
「リストの入れ子…ネストが深い時は、この deepcopy
を使うんだ。でも、別にリストとか入れ子にしてなけれ
ば、スライスの簡易コピーで十分だと思うよ」
「使い分けろってことね」
「そういうこと」
「喉が渇いたわ。お茶淹れてくるね。あんたも飲むわね」
「お願いします」
翔子が階下へ降りている間、巽は今日説明することを
整理していた。
リストに関しては、言うことが沢山あるのだ。
しばらくすると、翔子が木の盆の上に、急須と湯のみ
と菓子匣を載せて現れた。
「お母さんがお饅頭の美味しいの貰ってきたから、今日
はお煎茶ね」
急須の蓋を押さえて、とぽとぽと両手で注ぐ。
「はい」
「ありがと。そう言えばおばさんって、お茶の師範だっ
たよね」
「そうよ」
お茶菓子の供給ルートは、しっかりと確保されている。
「翔子は茶道とかやらないの?」
「う〜ん、お茶を飲んだりお菓子食べたりするのはいい
けど、御点前 (おてまえ) はちょっとね。おばあちゃん
とか、あたしに教えたがってたけど、そういうのあんま
り、我慢できないほうだから………って何よ。あたしに、
御点前でも習って、少しはおしとやかになれっていいた
いの?」
自覚、あるの?
「全然。それに僕は、そもそも茶道って、男のものだと
思ってるから。表千家とか裏千家とか、千家って茶の湯
の千利休の流れってことでしょ?」
絶対変だ、お前は
「まぁ、歴史的にはそうよね」
今ではすっかり、女性の嗜み(家元以外は)
「侘び寂びの世界じゃないけど、Python にも思想みたい
なものがあってね、実はこうすると、隠しメッセージが
見られるんだ」
>>> import this
「なにこれ………The Zen of Python…?」
是非、見て戴きたい
「Python の思想みたいなもんだってさ。『禅』っていう
のは洒落だけどね。ただ『わかりやすく』という一点に
すべて集約されるような文ではあるよ」
「わかりやすく、ね。でも、結構面倒だと思うけど」
「そうだね。プログラミングっていうのは結局作業だか
ら、作業内容が記述できなきゃならない。その限度は、
どうしてもあるだろうね。あと、人間が無意識に行う間
違いを、検出しやすいように、とかね。Python はそうい
うところを重点的に考えてデザインされてるけど、まだ
まだいろいろな批判があるのも事実だよ」
「道、遥かに険しく遠し………ってのは仏教っぽいわね」
「求道(ぐどう)に近いかもね」
「プログラマって求道者なの?」
「さぁ?」
絶対違う
「とりあえず再開しよっか」
「はいはい」
「前回、構文の一部として使った range っていう関数、
あれ、実際どういうものなのか、まず見てみよう」
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
「range 関数は、一つの数値だけを引数として渡した場
合、0 から始まって引数個の整数のリストを作るんだ」
「0から始まりっていうのは、またお約束?」
「もちろんそうだけど、実はコレが便利なんだよ」
「ふぅん」
「さて、本領発揮の使い方は後に回すとして………」
「なんで?」
「順番」
「ううう、厄介なヤツぅ〜」
「順番です。で、まぁ、例として使うリストを書くのに
便利なんだよね、これ」
>>> a = range(100)
>>> print a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
91, 92, 93, 94, 95, 96, 97, 98, 99]
>>>
「確かに 100 まで書くのは面倒くさそうだけど………こ
れが何?」
「この 100個の数値について、全ての要素について二乗
した数値を表示するっての、やってみよう」
>>> for x in a:
... print x ** 2,
...
0 1 4 9 16 25 36 49 64 81 100 121 144 169
196 225 256 289 324 361 400 441 484 529
576 625 676 729 784 841 900 961 1024 1089
1156 1225 1296 1369 1444 1521 1600 1681
1764 1849 1936 2025 2116 2209 2304 2401
2500 2601 2704 2809 2916 3025 3136 3249
3364 3481 3600 3721 3844 3969 4096 4225
4356 4489 4624 4761 4900 5041 5184 5329
5476 5625 5776 5929 6084 6241 6400 6561
6724 6889 7056 7225 7396 7569 7744 7921
8100 8281 8464 8649 8836 9025 9216 9409
9604 9801
>>>
「なんとなく、判ったような、判らないような………」
「for〜 in 文は、in の後に続くリストの中の要素を一
つずつ参照して、x の中に代入するんだ。で、while 文
のように繰り返すんだけど、その回数は、リストの要素
を全部参照し終わった時、ってことになるんだ」
「じゃ、ブロックの中のxの値って、毎回変わるの?」
「そういうことだね」
「参照は前から順番?」
「リストはね。そのうちやるけど、コレクションの中に
は順番の無いものもあるから、そういうのは目茶苦茶だ
よ」
一見メチャクチャに見えるが、実際はハッシュテーブ
ルという、ある法則に従った効率の良い順序に並んでい
る。
しかし、順序どおりではないので、人間の目からみれ
ばメチャクチャである。
「リストや文字列みたいに順序のあるコレクションは、
シーケンスって言うんだ」
「inの後って、リスト以外も入れられるの?」
「Python が最初から用意してるコレクションなら、何で
も入るよ。あと、この書式に対応する機能が用意されて
るものならいいよ」
「最初から用意されてるって?」
「ああ、リストとか文字列とか整数とか浮動小数点数と
か、いろんな値を扱ったけど、実は値の型(タイプ)っ
て、自由に自分で作れるんだよ。自分で作った型の場合、
この書式に対応する機能をちゃんとつけておけば、もち
ろん使えるよ」
「なんか奥が深いのね」
「言語仕様を全部使う必要は、全然無いからね。必要な
ものだけ、使えばいいということで」
「あ、そうなの」
「うん。僕らの目的は、プログラムを作ってコンピュー
タに作業させることであって、プログラミング言語の研
究者になることじゃないから」
「それはそうよね」
全ての学習に言えることだと思うのだが、果たして全
国の『先生』方が、どれだけそれを認識しているのだろ
うか?(実学主義と教養主義という違いはあるかもしれ
いないが)
「さて、じゃ、次行こう。今、画面に打ち出したけど、
これ、このまま消しちゃもったいないよね。結果をリス
トに入れたいんだけど、どうすればいいと思う?」
「え? あたしが考えるの?」
「そう」
「んっと………そうねぇ、こんなのどう?」
>>> a = range(100)
>>> for x in a:
... b = b + [x ** 2]
...
Traceback (most recent call last):
File "<stdin>", line 2, in ?
NameError: name 'b' is not defined
>>>
「あちゃ、またPythonがぶーたれてる」
「発想はいいんだけど、b がなんだかわからないうちに
連結に使ったのはまずかったね」
この辺りは、Python は他言語と比較して非常に厳しい。
宣言は必要無いが、定義されていない(値の代入され
ていない)変数の使用は、必ずエラーとなる。
また、浮動小数点数、整数、ロング整数などの変換は
自動に行われるが、文字から数値には、決して自動変換
されない。
「でも、最初っから入れたいから、要らないもの入れた
くないし………あ、そっか、削除だ」
「ん? やってみる」
「やってみる」
>>> b = [0]
>>> for x in a:
... b = b + [x ** 2]
...
>>> del b[0]
>>> print b
<省略>
「完璧っ! 完璧よねっ!」
「お見事。ただし実は、こういう書き方、出来るんだけ
どね」
>>> b = []
>>> for x in a:
... b = b + [x ** 2]
...
>>>
「………あ、あんた、ほ、ほ、ほんと―――――っに、
性格悪いっ! ぜぇ―――――ったい、女の子にモテな
いわよっ!」
それはどうだろう?
「いやだから、手持ちの道具で考えるのが重要なんだっ
て。だから翔子は間違ってないんだってば」
「考えて考えて考えたのをあっさり返されたら、ヤル気
失せるわよっ!」
確かに
「ごめん。でもね、結局プログラミングは思考する創造
作業なんだから、そういう考え方してれば、絶対損はし
ないって。それに、ブラケットの対で空リスト書く方法、
これで忘れないでしょ?」
しかし今回の翔子の機嫌は、コレくらいでは治まらな
かった。
「気分悪いわ」
「だから、謝ってるじゃないか」
「大体あんた、何様のつもり?」
「何様って………」
そろそろ巽は、翔子の様子がレッドゾーンを振り切っ
ているのに気づいた。
「あたしがが無様に失敗するの見て笑うほど、いつから
偉くなったのよ?」
「笑ってないって。僕はその方が勉強になると思って…
……」
「学校じゃあるまいし、プライド捨ててまで勉強したく
ないわ」
ごもっとも
「うう、どうしろって言うんだよ………」
少しの間、人差し指を唇に当てて考える翔子。
「そうね、明日学校終わった後、『デルフォイ』でケー
キセットおごり決定」
『デルフォイ』というのは、彼らの家の近くにある喫
茶店である。
店内は明るく、翔子のお気に入りの場所でもある。
「………おごるのはいいけど、あそこ、あまり落ち着か
ないんだけど………」
多分ソレは、君の名前と君の使ってる言語の呪いだろう
「あんたに選択権は無いわ」
「はい………」
「というわけで、続きね」
翔子の機嫌を損ねると高くつく、と、逆に学習した巽
だった。
「えっと………なんの話からだっけ?」
「空リスト」
怒って興奮したことが、嘘のように冷静である。
「あ、そうそう。リストの連結使う方法って、スライス
と同じで、リストを作り直すことになるから、ちょっと
無駄が多いんだよね」
「挿入を使うのね」
「そうそう」
「でも、挿入って、インデックス指定するのよね」
「うんうん」
「一回毎に、インデックスって増えてくのよね」
「そう、だから………」
「あ、そうか。一個づつ個数が増えるカウンタを作れば
いいのね」
「そうそう………え?」
>>> b = []
>>> c = 0
>>> for x in a:
... b[c] = x ** 2
... c += 1
...
Traceback (most recent call last):
File "<stdin>", line 2, in ?
IndexError: list assignment index out of range
>>>
「またぶーたれたっ!」
「………いや、それは予定内なんだけど………まさかそ
んな風に書くとは………」
初心者の行動を予測するのは、意外に難しいのだ。
「な、何よ、何か文句あるの?」
「まぁ………いいや。とりあえずエラーの方から説明す
るね。リストは、今無いインデックスを指定して挿入し
ようとすると、エラーを出すんだ」
「何よ、勝手に伸びてくれないの?」
「そうすると、連番が飛んだ時におかしな動作になるか
らね」
「じゃ、最初っから要素百個のリストを作って入れ替え
ればいいのね」
「それなら大丈夫」
「要素百個って………あ、range 関数使えば簡単じゃな
い」
学習能力は、基本的にずば抜けて高い翔子さん。
「それでもいいけど、ついでだからリストの掛け算やっ
とこうか?」
それを上回る注文をつける巽くん(またキレられても
知らないよ)
「掛け算?」
「そう。文字列でもやったけど、リストに整数を掛ける
と、内容が整数回数繰り返されるリストを作るんだ」
>>> p = [0,1,2] * 3
>>> p
[0, 1, 2, 0, 1, 2, 0, 1, 2]
>>>
「じゃ、空リストを………」
「ゼロは何回掛けてもゼロだよ。最低一個は入れてね」
「わ、わかってるわよっ! 空リストを要素にして、百
個作ろうと思ったのっ! 悪い?」
明らかに不自然な言動の翔子に、巽は気付かないフリ
をする。
「いいけど、リストってメモリ結構食うんだけど?」
「………整数のゼロにするわ」
>>> b = [0] * 100
>>> c = 0
>>> for x in a:
... b[c] = x ** 2
... c += 1
...
>>> print b
<省略>
「ふふふ、完璧ねコレ」
「悪いけど、まだ無駄があるよ」
「な、なぜよっ!」
「これは考えればわかるから、考えてみてよ。ヒントを
言えば、c は要らないよ」
「え? え? な、なんで?」
「だって、cと全く同じ値、もうあるから」
「へ? ……………あ、ああっ、あああああ―――――
っ!」
「わかった?」
「なによこれっ! cなんて要らないじゃないっ!」
「だからそう言ってるんだってば」
>>> b = [0] * 100
>>> for x in a:
... b[x] = x ** 2
...
>>> print b
「………でも、思うんだけど、これって a が range 関
数で作ったリストじゃなかったら、使えないんじゃない
?」
「うん。だから、例の文法が出てくるんだよ。a が不規
則な数値列だったとして、同じことができるように書い
てみよう。まず、range 関数で 0〜 19 までの 20個の整
数を作って、こいつを、random モジュールの shuffle
関数を使ってかき混ぜてみよう」
>>> from random import shuffle
>>> a = range(20)
>>> shuffle(a)
>>> print a
[0, 3, 2, 6, 1, 15, 19, 5, 8, 17, 4, 16,
11, 10, 13, 14, 12, 18, 9, 7]
>>>
「トランプゲームとか作るとき、使えそうな関数ね」
「乱数モジュールの random は、本来は解析なんかに使
うんだけど、ゲームに使えそうな関数もいっぱい入って
るから、そのうちゆっくり見てみよう。とりあえず今は、
さっきの続きだ」
>>> b = [0] * 20
>>> for x in range(20):
... b[x] = a[x] ** 2
...
>>> print b
[0, 9, 4, 36, 1, 225, 361, 25, 64, 289,
16, 256, 121, 100, 169, 196, 144, 324, 81, 49]
>>>
「あ、そっか。参照するリストも、インデックスで参照
すればいいんだ」
「前回は回数限定の話だけだったけど、for〜 in range
書式って、本来こんな使い方するんだよね」
「これで終わり?」
「最後に一個。次回に続く話として、リストを書き換え
ずに要素を加える方法を教えとくよ」
「え? できないんじゃないの?」
「できるけど、書き方が特殊なんだ」
>>> b = []
>>> b.append(5)
>>> print b
[5]
>>>
「ドットでつなぐのって、モジュールの名前を使う時じ
ゃなかったっけ?」
「今回は、『リストの機能』を使ってるんだよ。つまり
この場合は b の機能。こういうのを『メソッド』って呼
んでるんだよ」
「関数じゃないの?」
「似てるけど、ちょっと違うところは、ドットの前のモ
ノ………オブジェクトって呼んでるけど、オブジェクト
に関する機能ってとこかな。そのオブジェクトを操作し
たり、そのオブジェクトが持ってる値を使って計算した
り、とかね」
関数に見えても、実は関数ではなくメソッドだったり
その他のものであったりすることはよくある (先程使っ
た shuffle は実はメソッド)
しかし今はとりあえず、使い方として種類分けしてい
ると考えて欲しい。
「なるほど、今回はリスト自体の操作で要素を増やした
わけね」
「そういうこと。じゃ、これ使って、二乗のリストの最
終バージョン、書いてみて」
「オーライッ」
「ただし、無駄は省いてね」
「はいはい。………っと、えっと………、あれ? これ
もしかして………あ、できるじゃん。じゃ、これいらな
いから………」
>>> b = []
>>> for x in a:
... b.append(x ** 2)
...
>>> print b
[0, 9, 4, 36, 1, 225, 361, 25, 64, 289,
16, 256, 121, 100, 169, 196, 144, 324, 81, 49]
>>>
「で、できた」
「うん、append メソッドを使用すれば、インデックスを
参照する必要ないこと、よく気づいたね」
「苦労したわよ。学校の勉強より、数倍頭使ったわ」
「お疲れ様。今日はこれで終わりだよ」
「明日の約束、覚えてるでしょうね」
「覚えてるってば」
☆ ☆ ☆
翌日、喫茶『デルフォイ』にて。
巽、翔子が横に並び………そしてなぜか、向かいの席
には、美央と望美。
「で、なんで三人なんだ?」
「えっへっへ、悪いね朽縄くん」
「あ、あの………ごめんね」
「小さいこと気にしないの。どうせあんた、お大尽様で
しょ?」
「僕は身を削って稼いでるんだけど………」
「あ、あたしやっぱり………」
遠慮しようとする美央を、巽が制する。
「いいよ木崎。翔子が誘ったんだから、責任は翔子が持
つべきだ」
「そうそう、美央はおとなしく奢ってもらえばいいのよ」
調子に乗る望美を、ちろっとにらむ巽。
「坂下、お前は勝手に着いて来たんだろうがっ!」
「いいじゃない、大鳥先輩がいいって言ったんだから」
「そうそう、坂下ちゃんは局の人なんだから、仲良くし
とかなきゃね」
「袖の下なら、自分で出せよ」
「今日は巽のペナルティーなんだから、巽が出すの」
「中小企業の組合に接待代出させる政治家みたいなヤツ
だな、お前」
自治会も政治の一種と言えないことはない。
「ま、いいじゃない。あんたが女の子に奢る機会なんて
滅多にないんだし、可愛い女の子に囲まれてハーレム状
態なんだから、翔子お姉さまのご配慮に感謝しなさいよ」
「ハーレム・ハーレム♪」
「うう、もういいよ。判った。あきらめた。今日は全部
僕が持つ」
「や、やっぱりあたし………」
望美はこっそり、美央を肘でつつく。
(なによ)
(奢られておきなさいって。もし悪いと思うなら、後で
朽縄くんに、何かお返しすればいいでしょ?)
(あ、そっか)
(ったく、こんなのはいい口実なのに、チャンス逃がし
てどうするのよ)
(ちゃ、ちゃんすって………)
(あたしが気付かないとでも思った? 美央、あんた朽
縄くんに気があるんでしょ?)
(! ! ! ! !)
(バレバレよ。でも、想像以上に大鳥先輩は手ごわいわ。
だから、機会つかんで積極的にアピールしなきゃ)
(だ、だって………そ、そんなこと言うなら、望美だっ
て昨日………)
(うん。あたしも隙あらば狙うよ。覚悟しといてね)
(え、ええっ?!)
「ちょっとぉ、なに二人でこそこそ話してるの?」
「女の子同士の話だろ? ほっとけよ」
「あんた、あたしが女の子だって自覚、あるの?」
「逆に翔子自身に自覚があるのか、聞きたいね」
「あるに決まってるじゃない」
「あっそ。じゃ、翔子の思ってる『女の子』の定義では、
『女の子』と見なしてるよ」
「木崎ちゃんや坂下ちゃんは、違う『女の子』の定義な
わけ?」
「僕的には」
「どう違うのよ」
「僕が受ける被害の度合いが………」
「何寝ぼけてるのよ。女の子が男に迷惑かけるのは、当
然なの」
「当然………なのか………(汗)」
(そうなの、望美?)
(ある面、そうは思うけど、この人、ストレートに言う
の?)
(大鳥先輩だから)
(そ、そうなの)
「特にあんたは、あたしに尽くす星の下に生まれてきた
の」
(絶対所有宣言してるし)
「星辰の運行を逆転させても、否定したいぞ、ソレは」
(あ、でも、朽縄くん、否定してる)
(う〜ん、嫌がってるのか、対等に扱われたいのか、微
妙なトコね)
「宇宙の法則に逆らう気?」
「翔子中心の宇宙の法則なんかに全て従ってたら、僕の
命があっという間に磨耗する」
(単に身の危険を感じてるだけみたいね)
(大鳥先輩も、そこまでキツくないと思うけど)
(なによ美央、あんたどっちの味方?)
(え? で、でもあたし、大鳥先輩も好きだし)
「何よあんたの命くらい、大した事無いでしょ?」
(……………)
(……………)
「ん? 翔子、木崎たち、話終わったみたいだぞ」
「そうなの? じゃ、折角こうして集まってるんですも
の、もっとお話しましょ?」
「………あ、あのぉ、大鳥先輩と朽縄くんって………い
つも今みたいな会話してるんですか?」
「ん? そうね、普通の会話よ」
「そうだな。普段からこんな感じ。なんか変か、坂下?」
自覚無いのか、あんたら
「望美、どうしたの?」
「ふふふ」
「え?」
「ふふふふふふ、燃えてきた燃えてきた。なんか知らな
いけど、妙に燃えてきたっ!」
「の、望美?」
「大島先輩っ! 朽縄くんっ! サイコーですっ!」
「え? 何が?」
「『最高』とか『傑作』ってのは、『面白い』って意味
だよ」
巽は紅茶を啜りながら、冷静に突っ込む。
「そうなの? 別に面白いこと、無いと思うけど?」
「いいじゃないか、本人が面白がってるんだから、ほっ
とけば」
「朽縄くんも、十分面白いわよ」
「望美、いくらなんでもそれ、失礼なんじゃ………」
「ああ、別に構わないよ。僕と翔子の掛け合い見ててム
カツクとかいうより、マシだよ」
「えっと………朽縄くんがそれでいいなら」
「いいよ。こっちも十分楽しませてもらってるから。そ
れにこれだけ翔子がノるのも、機嫌がいい証拠だからね」
「え? そ、そうだったの?」
「わかんないだろ? 難しいんだよ、こいつの機嫌読む
の」
「へぇ、やっぱ朽縄くんって、大鳥先輩のこと、よくわ
かってるんだ。ホントに幼なじみだけの関係なの?」
「ちがうわ、坂下ちゃん」
「え? じゃ、じゃぁ、やっぱり」
「ご主人様と犬よ」
劣化ウランのように重苦しい沈黙が、辺りを包んだ。
<翔子のノート(ロンより翔子?)>
Lesson.5
リストの書き方
[要素1, 要素2, 要素3, ...]
インデックスによる要素の入れ替え
リスト名[インデックス] = 要素
インデックスによる要素の削除
del リスト名[インデックス]
リストの連結
リスト + リスト
リストのくり返し
リスト * 整数
入れ子になったリスト
[要素1, 要素2, [要素3, 要素4], 要素1]
2変数による同一リストの参照
x = <リスト>
y = x
リストの表層コピー
y = x[:]
リストのディープコピー(完全な複製)
from copy import deepcopy
y = deepcopy(x)
range関数の使い方(その1)
range(x)⇒[0, 1, 2, ... (x-2), (x-1)]
for文によるコレクションの全数検査
for 変数 in コレクション:
<文>
for文による、インデクシング
for カウンタ in range(要素数):
<後記>
リストは書き残しが一杯ですが、強制的に次は辞書
(ディクショナリ) の話へ。回数はやっと折り返し。一通
り話せるか不安です(体力的にも若干不安………)