ゆとり大学院生の日常~なんかいいことないかな~

留年と隣り合わせの情報系大学院生の日常。

リストとタプル

こんにちは。留年予備軍です。 今回は整数や文字列などのデータを組み合わせて作られるデータ構造(リストタプル)をご紹介したいと思います。

シーケンス型とは

データ構造についてお話しする際にシーケンス型について説明しないといけません。

シーケンス(英語ではSequence)とは連続、一続きのものを表す英単語でpythonにおいては広い意味で一続きのデータという意味で用いられています。

つまりシーケンス型とは数字や文字などのデータの集まりでかつデータに順序が存在するデータ構造を指します。

今回お話しするデータ構造の中ではリスト、タプルが該当します。

またpythonにおいて基本的なシーケンス型はリスト、タプル、rangeオブジェクト(rangeオブジェクトはまたの機会にしたいと思います。。。)があります。
(これはpython公式ドキュメント 標準ライブラリ4.6 シーケンス型を参考にしました。pythonの公式ドキュメントはわかりやすく正確でまた親切な方々が翻訳までしてくれているので頻繁に参照してもいいと思います。翻訳はラグがあるので最新情報がほしい方はぜひ原文(英語)を参照してください。)

あとは'abc'のような文字列もシーケンス型に該当します。

リストタプル

リストタプルは0個以上の要素を持てるデータ構造で、要素の型は任意です。

リストは[]で囲んで作ります(またはlist()の括弧で囲んで作ります)。 具体的に言えばドラえもんのキャラクタの名前を文字列として持つリストcharacters_of_Doraemonは以下のようになります。

characters_of_Doraemon = ['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka', 'Dekisugi']

タプルは()で囲んで作ります(またtuple()で括弧でシーケンス型を囲んでも作れます)。具体例を先ほどのドラえもんの例にすると

characters_of_Doraemon = ('Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka', 'Dekisugi')

となります。

ちなみに要素の型を調べるにはtype()を使います。例えばa = 7として対話型インタープリタでaの型を調べたければtypeを用いて以下のようになります。よってaはint型であることが分かります。

>>> a = 7
>>> type(a)
<class 'int'>

すいません、脱線してしまいましたが。。。
リストタプル複数の要素を持つことができるデータ構造であるということがわかりました。

それではリストタプルは何が違うのでしょうか?

リストタプルの違い

リストタプルには決定的な違いがあります。 その違いとはリストミュータブル(格納されているデータの値が変更可能である)で、タプルイミュータブル(格納されているデータの値を変更できない)ということです。 これがどういったことに影響するかについて考えます。

具体例でみるリストタプル

先ほどのドラえもんの具体例ドラえもんの主要キャラの名前を格納したデータ構造を考えます。

以下は僕が以前書いた記事なんですがミュータブル・イミュータブルと変数の扱い方が密接な関係にあるので参照していただけたらと思います。

repeterreservearmy.hatenablog.com

この記事でpythonにおいて変数はデータの参照であるということを述べました。これを踏まえて変数aにドラえもんの主要キャラの名前をリストに格納します。

>>> a = ['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka', 'Dekisugi']

それを変数bに代入します。

>>> b = a

今aとbにはドラえもんの主要キャラの名前がそれぞれ格納されているはずです。実際に見てみると

>>> a
['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka', 'Dekisugi']
>>> b
['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka', 'Dekisugi']

と同じデータが格納されています。

ここである人が出木杉君だけキャラが立っていない(?)という理由で勝手に変数aから出木杉君を削除するコードを書いたとします。

>>> a.remove('Dekisugi')
>>> a
['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka']

となって出木杉君が削除されてしまいました。

しかし主要キャラは出木杉君を主要メンバーの名前と映画のタイトルを返す関数movie()出木杉君含めて表示しようとしたあらかじめaの値を代入したbを使って

>>> def movie(characters):
...      print('member:',characters, "Doraemon: Nobita's Dinosaur")
...
>>> movie(b)
member: ['Draemon', 'Nobita', 'Suneo', 'Jyaian', 'Sizuka'] Doraemon: Nobita's Dinosaur

となって出木杉君が削除されて表示されてしまいます。

なんかごちゃごちゃしてきましたが、ミュータブルであるデータ構造であるリストを使うと決まった値だと考えていたものが変わっているなどの予想外なことが起こりえます。

なので不変のものを定義するときはイミュータブルにしておきましょう!(ドラえもんの主要キャラは出木杉君も含まれています、異論は認めません(笑))

理系の方とかだと光速cとかは不変値で変更しないものなのでイミュータブルにしておきましょう!

長くなりましたが複数要素を格納できるリストタプルは頻繁に使うと思うので違いを押さえておきましょう!

今回はこれで失礼します!