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になってしまう…。言語の設計は難しい…。