« 執筆日記8 |Main| 執筆日記9 »

« 差分リストを作るには | Python | PythonでRubyっぽいmap »

Pythonにおけるタプルの存在意義 リターンズ

書き足しているうちに長くなったので日記から転載しました。 昔書いたよくない説明→Pythonにおけるタプルの存在意義

__ タプルの分かりやすい説明 ? Weboo! Returns.。 なるほど、本とリフィルにたとえるのですね。

僕のJython本の解説では袋と真空パックになっています。

おおざっぱなイメージとしては 「リストはいくつものモノを入れることのできる長細い袋で、 タプルはいくつかのモノの入った真空パックだ」と言えます。
でも最近はもうタプルとリストの違いを説明するのに飽きてきて、 なんでタプルなんかがあるのかとこちらが問いたい気分。 全部リストでいいじゃないか、と。 タプルが必要なところだけ勝手に変換すればいいじゃないか、と。 要素が1個のタプルが美しくないよ、と。 タイムマシンでPythonが公開される前に戻れるのなら、 「タプルはやめて」と進言したい(笑)

mutable、immutableという言葉を使った説明も僕のJython本ではしない予定。 だって変更可能なものはハッシュのキーになれませんとか言うけど、

>>> class Foo:
...     value = []
...
>>> {Foo: 1}
{<class __main__.Foo at 21859329>: 1}
>>> Foo.x = 1
>>> Foo.value.append(2)
どう見てもこのFooってオブジェクトは変更可能に見えるでしょう。 少なくともJythonの実装では、クラスオブジェクトPyClassは __hash__をPyObjectクラスから継承していたりするので、 PyListが同じことをできない技術的な理由は全くないわけです。

おそらく 「{[]: 1, []: 2}」 という状態が起きるのを快く思わなかったのでしょう。 リストもタプルも、2つ作れば2つとも別のインスタンスなので、 PyObjectと同じidベースのハッシュ関数ではこういう状態が起きてしまいます。 それを避けるために「中身を見て同じなら同じと判断する」 という「特殊なリスト」(後のタプルである)をつくったのでしょう。

今になって思えば、この「タプルとリストって何が違うんだ」という質問の多さを考えると 「{[]: 1, [], 2}」を許容してしまった方がよかったのではないかと。 「なんで同じ[]をキーにして複数のエントリがあるんですか?」 「あー、たまたま両方とも空っぽだから同じに見えるけど別のオブジェクトだからね。 片方に何かをappendしてももう片方は影響受けないでしょー」

>>> a = []
>>> b = []
>>> a is b
0
>>> a.append(1)
>>> a
[1]
>>> b
[]
こっちの説明のほうがよっぽど楽です。

__ あっ、ダメだ。その仕様だとdata[(1, 2)] = 3ってやってから後でprint data[(1, 2)]ってやってもKeyErrorになってしまう…。言語の設計は難しい…。

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/509

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.