3.2. リストの紹介

リストは Python の働き者のデータ型です. もし Visual Basic の配列や Powerbuilder のデータストア (なんと!) でしかリストに触ったことがないなら, 心して Python のリストに取り掛かってください.

Note
Python のリストは Perl の配列に似ています. Perl では, 配列を格納する変数は必ず @ 文字から始まります. Python では変数名は任意であり, Python は内部的にデータ型を把握しています.
Note
Python のリストは Java の配列以上のものです (とはいえ, ただ単に配列のように使いたいのであれば, その通りに使えます). どちらかと言うと, 任意のオブジェクトを保持でき, 新しい要素が追加されたときに動的に拡張される ArrayList クラスに例える方が適切です.

3.2.1. リストの定義

Example 3.6. リストの定義

>>> li = ["a", "b", "mpilgrim", "z", "example"] 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0]                                       2
'a'
>>> li[4]                                       3
'example'
1 まず最初に, 5 つの要素を持つリストを定義します. 元々の要素の順番を保持していることに注意してください. これは偶然ではありません. リストは角括弧で括られた順序付きの集合です.
2 リストは 0-起点の配列のように使えます. 空でないリストの最初の要素は常に li[0] です.
3 5 つの要素を持つリストの最後の要素は li[4] で, これはリストが常に 0-起点だからです.

Example 3.7. リストの負のインデックス

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1] 1
'example'
>>> li[-3] 2
'mpilgrim'
1 負のインデックスはリストの最後から逆向きに数えて要素にアクセスします. 空でないリストの最後の要素は常に li[-1] です.
2 もし負のインデックスに混乱するようなら, 次のように考えてください. li[-n] == li[len(li) - n]. なのでこのリストでは, li[-3] == li[5 - 3] == li[2] となります.

Example 3.8. リストのスライス

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3]  1
['b', 'mpilgrim']
>>> li[1:-1] 2
['b', 'mpilgrim', 'z']
>>> li[0:3]  3
['a', 'b', 'mpilgrim']
1 2 つのインデックスを指定して, “slice” と呼ばれるリストの部分集合を得ることができます. その返り値は新しいリストで, 1 つ目のスライスインデックス (この例では li[1]) から 2 つ目のスライスインデックス (この例では li[3]) の手前までのリストの要素を全て順序を保ったまま保持しています.
2 スライシングは, スライスインデックスの片方もしくは両方が負であってもきちんと動きます. 次のように考えるといいかもしれません. リストを左から右に読んでいき, 最初の欲しい要素を 1 つ目のスライスインデックスが指しており, 最初の欲しくない要素を 2 つ目のスライスインデックスが指しています. 返り値はその間にある全てです.
3 リストは 0-起点なので, li[0:3]li[0] から li[3] の手前までの, リストの最初の 3 要素を返します.

Example 3.9. スライシングの略記

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3] 1
['a', 'b', 'mpilgrim']
>>> li[3:] 2 3
['z', 'example']
>>> li[:]  4
['a', 'b', 'mpilgrim', 'z', 'example']
1 もし左のスライスインデックスが 0 だったらそこは空にしておけ, それが 0 を示すことになります. なので li[:3]Example 3.8, “リストのスライス”li[0:3] と同じです.
2 同様に, 右のスライスインデックスがリストの長さだったら, そこは空にしておけます. なので li[3:] は, リストが 5 つの要素を持っているので li[3: 5 ] と同じです.
3 ここでは対称性に注意しましょう. 長さ 5 のリストでは, li[:3] は最初の 3 要素を返し, li[3:] は最後の 2 要素を返します. 実際リストの長さに関わらず, li[:n] は常に最初の n 要素を返し, li[n:] は残りの要素を返します.
4 もし両方のスライスインデックスとも空にしておくと, 全ての要素を含んだリストが返ってきます. しかし, これは元のリスト li そのものではなく, 全く同じ要素を持つ新しいリストです. li[:] はリストの完全なコピーを作るための略記方法です.

3.2.2. リストへの要素の追加

Example 3.10. リストへの要素の追加

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")               1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new")            2
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"]) 3
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 append はリストの末尾に 1 つ要素を追加します.
2 insert はリストに 1 つ要素を挿入します. 整数引数は, 挿入により押し出される要素のうち最初の要素のインデックスです. リストの要素は重複があってもよいことに注意してください. 今, 'new' という値を持った別々の 2 つの要素が li[2]li[6] にあります.
3 extend はリストを連結します. 複数引数で extend を呼んではいないことに注意してください. 引数は 1 つで, それはリストです. この例では, 引数のリストは 2 つの要素を持っています.

Example 3.11. extendappend の違い

>>> li = ['a', 'b', 'c']
>>> li.extend(['d', 'e', 'f']) 1
>>> li
['a', 'b', 'c', 'd', 'e', 'f']
>>> len(li)                    2
6
>>> li[-1]
'f'
>>> li = ['a', 'b', 'c']
>>> li.append(['d', 'e', 'f']) 3
>>> li
['a', 'b', 'c', ['d', 'e', 'f']]
>>> len(li)                    4
4
>>> li[-1]
['d', 'e', 'f']
1 リストには, extendappend という, 同じことをしているように見えて実際は全く異なる 2 つのメソッドがあります. extend は引数を 1 つだけ, かつ必ずリストを引数に取り, そのリストの要素それぞれを元のリストに追加します.
2 ここでは 3 つの要素 ('a', 'b', 'c') を持つリストから始めて, 3 つの要素 ('d', 'e', 'f') を持つリストで拡張したので, リストの要素は 6 つになりました.
3 一方, append は任意のデータ型の引数を 1 つ取り, 単純にリストの末尾に追加します. ここでは, 3 つの要素を持つリストを引数に与え append を呼び出しています.
4 すると最初 3 つの要素を持っていたリストは, 今 4 つの要素を持っています. なぜ 4 つなのでしょうか? なぜなら, 末尾に追加した要素はリストそのものなのです. リストは, 他のリストを含め任意の型のデータを保持することができます. これは望んだ結果かもしれませんし, そうでないかもしれません. extend のつもりで append を使ってはいけません.

3.2.3. リストの探索

Example 3.12. リストの探索

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example") 1
5
>>> li.index("new")     2
2
>>> li.index("c")       3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li           4
False
1 index はリストの中から値が最初に出てくるところを見付け, そのインデックスを返します.
2 index はリストの中から値が最初に出てくるところを見付けます. この例では, 'new' はこのリストの li[2]li[6] に 2 回現れますが, index は最初の方のインデックスである2を返します.
3 もし値がリストに見付からなかったら, Python は例外を送出します. この動作はほとんどの言語が無効なインデックスを返しているのとは顕著に違います. これは困った動作に見えますが, 実は良いことなのです. なぜならこれは, 無効なインデックスを使おうとした箇所ではなく, index を呼び出した箇所で, プログラムが停止するということだからです.
4 値がリストに入っているか確かめるためには in を使います. これは, 値がリストに見付かれば True を返し, そうでなければ False を返します.
Note
バージョン 2.2.1 以前, Python は専用の論理値用データ型を持っていませんでした. その代わりに, Python は (if 文のような) 論理値を期待する文脈で, 次のルールに従ってほとんどのものを受け入れていました.
  • 0 は偽, それ以外の全ての数字は真.
  • 空文字列 ("") は偽, それ以外の全ての文字列は真.
  • 空のリスト ([]) は偽, それ以外の全てのリストは真.
  • 空のタプル (()) は偽, それ以外の全てのタプルは真.
  • 空の辞書 ({}) は偽, それ以外の全ての辞書は真.
これらのルールは Python 2.2.1 以降でもまだ適用されますが, 今は TrueFalse という値を持つきちんとした論理値も使えます. 大文字小文字の違いに注意してください. Python の他の全てのものと同じように, これらの値でも大文字小文字が区別されます.

3.2.4. リストの要素の削除

Example 3.13. リストから要素を削除する

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z")   1
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new") 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c")   3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop()         4
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 remove は, リストの中の値が最初に出てくるところを削除します.
2 remove は, リストの中の値が最初に出てくるところのみを削除します. この例では, 'new' はリストの中に 2 回現れているが, li.remove("new") は最初に出てきたもののみ削除しました.
3 もし値がリストの中に見付からなかったら, Python は例外を送出します. これは index の動作と似ています.
4 pop は興味深い獣です. その獣は 2 つのことをします. リストの最後の要素を削除し, その削除した値を返します. これは, 値は返すがリストに変更は加えない li[-1] や, リストに変更を加えるが値を返さない li.remove(value) とは異なっていることに注意してください.

3.2.5. リスト演算子の使用

Example 3.14. リスト演算子

>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new'] 1
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two']                2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3              3
>>> li
[1, 2, 1, 2, 1, 2]
1 リストは + 演算子でも連結できます. list = list + otherlistlist.extend(otherlist) と同じ結果になります. しかし, extend が今あるリストを変更するのに対して, + 演算子は新しい (連結) されたリストを返します. これは extend の方が, 特に大きなリストで, 速いことを意味しています.
2 Python+= 演算子もサポートしています. li += ['two']li.extend(['two']) と同等です. += 演算子はリスト, 文字列, 整数に作用し, ユーザが定義したクラスに対しても作用するように, オーバーロードすることが可能です. (これについては 5 章 でさらに扱います.)
3 * 演算子は反復子としてリストに作用します. li = [1, 2] * 3li = [1, 2] + [1, 2] + [1, 2] と同等で, 3 つのリストを 1 つのリストに連結します.

リストについてさらに知るには