連載
» 2019年05月31日 05時00分 公開

Python入門:[Python入門]リストの基本 (2/4)

[かわさきしんじ,DeepInsider編集部]

リストの要素

 先ほども述べたが、リストに格納された個々のデータのことを「要素」と呼ぶ。要素には、0始まりで「インデックス」が与えられ、リストを代入した変数(あるいはリストそのもの)に「[インデックス番号]」を続けることで、個々の要素にアクセスできる。イメージとしては、第6回「文字列の操作」の「文字列の要素を取得する:インデックス指定」で見た文字列の要素のインデックス指定と同様だ。以下に先ほど作成したリストlanguagesとそのインデックスを示した画像を再掲する。

リストの要素には0始まりでインデックスが付けられる(再掲) リストの要素には0始まりでインデックスが付けられる(再掲)

 例えば、「languages[0]」とすれば、文字列'Python'が取り出せるということだ。

リストlanguagesにインデックスを付加して、0番目の要素を取り出したところ リストlanguagesにインデックスを付加して、0番目の要素を取り出したところ

 なお、上で見たリストの要素は全て文字列となっていたが、実際にはリストにはさまざまな種類のデータを混在させて格納できる。

somelist = ['python', 1, 100.5]
print(somelist)

リストに文字列、整数、実数(浮動小数点数)を格納する

 上のコードを実行した結果を以下に示す。

リストには任意の型の値を混在させて格納できる リストには任意の型の値を混在させて格納できる

 文字列同様、インデックスにマイナスの値を指定できる。インデックスに「-1」は末尾の要素に、「-2」はその手前の要素に、……、というのも文字列と同様だ(例は省略)。

リストの要素のスライス

 文字列では、インデックス指定の代わりに「[start:end:step]」のようにして、文字列の特定の位置にある複数の文字を一度に取り出せた。これを「文字列のスライス」と呼ぶ。リストでも同様な操作が可能だ。以下に例を示す。

intlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(intlist[1:4])  # インデックス1からインデックス3までの3つの要素を取得
print(intlist[:3])   # インデックス0からインデックス2までの3つの要素を取得
print(intlist[5:])   # インデックス5以降の要素を取得
print(intlist[1:9:2])  # インデックス1〜8までの範囲にある要素を1つ飛ばしで取得

リストのスライス

 ここではインデックスと、そのインデックスで得られる要素が一致するように「0」〜「9」の10個の整数値を要素とするリストintlistを定義している。文字列と同様に、スライスを行うときには「[start:end]」で指定した「end」の1つ手前の要素までが抜き出されることには注意しよう。そのため、最初の例「intlist[1:4]」では「インデックス1」の位置にある整数値「1」から「インデックス4の手前」つまりインデックス3の位置にある要素「3」までが取得される。

 「start」を省略するとインデックス0が指定されたものと見なされ、「end」を省略すると最後の要素までが対象となり(この場合はlen(intlist)が指定されたものと同様)、「step」を省略すると「1」が指定されたものと見なされるのも文字列のスライスと同様だ。

 上のコードを実行した結果を以下に示す。コメントと照らし合わせながら、実行結果を確認してほしい。

実行結果 実行結果

リストの要素の変更

 リストの要素は「変更可能」だと上で書いた。これは、リストの要素の値を別の値で書き換えられることを意味している(これは文字列の要素が変更不可能であるのと反対だ)。例えば、上で作成したリストの3番目(インデックス2)の要素'PHP'を'JavaScript'に置き換えるには次のコードを実行する。

languages = ['Python', 'Ruby', 'PHP']
print(languages)
languages[2] = 'JavaScript'
print(languages)
print(languages[2])

リストの要素を変更するコード

 これをセルに入力して実行した結果を以下に示す。

リストlanguagesの要素2(3番目の要素)が変更されたことが分かる リストlanguagesの要素2(3番目の要素)が変更されたことが分かる

 上に示した通り、リストの3番目の要素が書き換えられていることが分かる。

 スライスした結果へ代入することも可能だ。このとき、代入可能なのはリストなどの「反復可能オブジェクト」となる。以下に例を示す(ここでも、動作を理解しやすくなるように、要素の値とインデックスが一致するようなリストを作成している)。

intlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
intlist[0:5] = [10, 11, 12, 13, 14# 先頭から5つの要素を変更
print(intlist)  # [10, 11, 12, 13, 14, 5, 6, 7, 8, 9]
intlist[0:2] = [20, 21, 22# 先頭から2つの要素を書き換え(余った文は追加)
print(intlist)  # [20, 21, 22, 12, 13, 14, 5, 6, 7, 8, 9]
intlist[0:6] = [0, 1, 2# 先頭から6つの要素を変更(足りない部分は削除される)
print(intlist)  # [0, 1, 2, 5, 6, 7, 8, 9]
intlist[0:2] = 1  # エラー

リストのスライスを使って、その要素を変更する

 スライスで得られるオブジェクト(スライスオブジェクト)への代入では、元のオブジェクトの要素数と代入する反復可能オブジェクト(リストなど)の要素数が同じでなくても構わない。代入する方の要素が多ければ、それらが該当する位置に追加される。少なければ、元のリストから要素が削除される。上のコード例を参考にしてほしい(コード例は示さないが、空のリスト「[]」を代入すると、該当する要素が全て削除される。興味のある方は試してみよう)。最後の行ではリストではなく、整数値「1」を代入しているが、これはエラー(TypeError例外)となる。以下に実行結果を示す。

実行結果 実行結果

 なお、step値まで指定した場合には、代入先と代入元の要素数が一致する必要があるので、そこには注意しよう。以下に例を示す。

intlist = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
intlist[0:10:2] = [10, 12, 14, 16, 18# 先頭要素から1つ飛ばしで5個を変更
print(intlist)  # [10, 1, 12, 3, 14, 5, 16, 7, 18, 9]
intlist[0:10:2] = [20, 22# エラー

リストをスライスしたものに代入するときには、要素数が一致している必要がある

 このコードを実行すると、最初の代入では「intlist[0:10:2]」で得られるスライス(インデックス0、2、4、6、8の位置にある5つの要素)の要素数と、代入するリストの要素数が同じなので問題なく代入できる。だが、最後の行では要素数が異なっているのでエラー(ValueError例外)が発生する。

 実行結果は以下の通りだ。

実行結果 実行結果

リストへの要素の追加

 一度作成したリストには、要素を追加していくことも可能だ。これには、リストが持つ「append」という名前の「メソッド」を使用する。第6回「文字列の操作」の「文字列に特定の文字列が含まれているかを調べる:in演算子、find/rfind/index/rindexメソッド」でも少し触れたが、「メソッド」とは「オブジェクトが自分自身を対象として何らかの処理を行うために使える関数」のようなものだ。

 メソッドは、関数と同様に、引数を受け取り、操作対象(この場合はリスト)に対して何らかの処理を実行する。メソッドを実行するには「操作対象.メソッド名(引数)」のような形で呼び出す。以下の例では、操作対象はリストを代入した変数languagesであり、引数には追加する要素を指定する。そのため、appendメソッドは「languages.append(引数)」のような形で呼び出す。

languages = ['Python', 'Ruby', 'PHP']
languages.append('Perl')
print(languages)

appendメソッドでリストに要素を追加

 上のコードを実行した結果を以下に示す。

プログラミング言語のリストにPerlが追加された プログラミング言語のリストにPerlが追加された

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。