こんにちは(@t_kun_kamakiri)(‘◇’)ゞ
この記事ではPythonのデータの型の中の「リスト型」について解説します。
まずデータの型についてですが、以下の種類があります。
- 数値型
- 整数
- 浮動小数点
- 複素数
- 文字列
- リスト型
- 辞書型(ハッシュ)
- タプル型
- 集合型
- 論理型
これらすべて完璧に使い方を覚える必要はないと思いますので、この記事では「これくらいは覚えておこう」というものをまとめておきます。
その中でも本記事では「リスト型」について解説します。
基本的なことをまとめておきました。
- Pythonのリスト型とは?
- リストの要素の取り出し
- リストの要素の追加・削除・更新の方法
- その他リスト型の関数とメソッド
こちらの本がPython初心者が挫折することなく勉強できる本です。
(本記事のようのPython使用環境と異なりますが、とてもわかりやすいので全く問題ありません)
リスト型とは?
数値型や文字列はそれ自体でひとつのデータ(値)でしたが、リスト型は複数のデータをひとまとまりに扱うことができます。
まずは、リスト型の書き方から確認しましょう。
リスト型は[ ]で囲み、データを「,(カンマ)」で区切る。
1 | 変数 = [要素1, 要素2, 要素3, 要素4] |
という感じで書きます!
実際に、Google Colabでコードを書いて出力結果を確認してみましょう。
1 2 3 4 5 6 | a = [1,2,3,4,5] b = [1,'kamakiri',32] print(a,type(a)) print(b,type(b)) |
print文で「変数aと、aのタイプ」「変数bと、bのタイプ」を出力しています。
【結果】
1 2 | [1, 2, 3, 4, 5] <class 'list'> [1, 'kamakiri', 32] <class 'list'> |
タイプについては、それぞれ「list」と返ってきているのでリスト型になっているのがわかります。
以下のように、リストにリストを要素として入れることができることも覚えておきましょう。
1 2 3 4 5 6 7 8 | #リストにリスト要素を入れることもできる。 list = [ [1,2,3], ['kamakiri','apple'] ] print(list) |
【結果】
1 | [[1, 2, 3], ['kamakiri', 'apple']] |
リストの要素を取り出す
次に、用意したリスト型の各要素を取り出す方法について解説します。
【ポイント】
- リストのインデックス(Index)を指定して要素を取り出す
- リストのインデックス(Index)は0からはじまる
リストの要素を取り出すには、以下のように書きます。
1 | リスト = [インデックス] |
ここで気を付けないといけないのが、リストのインデックスは0からはじまるということです。
なので、以下のように最初の要素を取り出したいときには、インデックスは0に指定する必要があります。
リストの2番目の要素を取り出したいときは、インデックスは1に指定する必要があります。
では、Google Colabでコードを書いてみましょう。
1 2 3 4 5 | b = [1,'kamakiri',32] print(b[0]) print(b[1]) print(b[2]) |
print文で結果を出力してます。
【結果】
1 2 3 | 1 kamakiri 32 |
以下のような、変数aについても確認してみましょう。
1 2 3 4 5 6 7 8 | #要素を取り出す a = [1,2,3,4,5] print(a[0]) print(a[1]) print(a[2]) print(a[3]) print(a[4]) |
【結果】
1 2 3 4 5 | 1 2 3 4 5 |
インデックスは0からはじまることに注意しないと、思った結果になってくれないので注意が必要です。
※要素を取り出すのに、ひとつひとつインデックスを指定して要素を取り出していてはとても面倒なので、以下のスライスという方法を使ってはめちゃくちゃ簡単に特定の範囲の要素を取り出してみます。
リスト内の範囲を指定して要素を取り出す
ここでは、スライスを使う目的についてまとめておきます。
【スライスの目的】
- リスト内の特定の範囲を簡単に取り出せる
- リスト内の要素をひとひとつ取り出す方法より、スライスを使う方が計算時間が早い「スライス」についての記事はこちら
スライスを使って特定の範囲の要素を取り出す基本的な記述は以下のように書きます。
実際にコードを書きながら確認してみましょう。
- リスト内のすべての要素を取り出すとき
1 | リスト[:] |
すべての要素を取り出す。
1 2 3 4 | #要素を取り出す a = [1,2,3,4,5] print(a[:]) |
【結果】
1 | [1, 2, 3, 4, 5] |
すべての要素を取り出すことができました。
- リスト内の特定の範囲を指定して要素を取り出すとき
1 | リスト[開始インデックス: 終了インデックス ] |
1 2 3 4 | #要素を取り出す a = [1,2,3,4,5] print(a[0:2]) |
【結果】
1 | [1, 2] |
特定の範囲の要素のみを取り出すことができました。
- インデックスを飛ばし飛ばし取り出したい場合は、ステップ数を指定する
1 | リスト[開始インデックス: 終了インデックス : ステップ数] |
1 2 3 4 | #要素を取り出す a = [1,2,3,4,5] print(a[0:4:2]) |
【結果】
1 | [1, 3] |
以上のようにスライスを使えば簡単に特定の範囲(もしくは全範囲)の要素を取り出すことができます!
- 最後からいくつ前のインデックスまで取り出すかを指定する
1 2 3 4 | #要素を取り出す a = [1,2,3,4,5] print(a[:-2]) |
【結果】
1 | [1, 2, 3] |
はじめはスライスは慣れないですが、試しに色々とコードを書いてみてどういった出力がされるのかを確認することで、理解が深まると思います。
リストに要素を追加・削除・更新を行う
ここでは、以下の絵のようにリスト内の要素を追加したり削除したり更新したり・・・・要素内を自由にイジル方法を学びます。
【ポイント】
- リストに要素を追加
要素を追加➡append()メソッド
リストに別のリストを追加➡extend()メソッド
指定した位置に要素を追加➡insert()メソッド - リストの要素を削除
要素の値を削除➡remove()メソッド
要素のインデックスを指定して値を削除➡pop()メソッド - リストの要素の更新(リストのインデックスを指定して値を入れ替える)
ひとつひとつ確認しましょう。
リストに要素を追加
要素を追加➡append()メソッド
まず、以下のように「変数a」というリストを用意しておき、append()メソッドで要素を追加していきます。
1 2 3 4 5 6 7 8 9 10 11 | #リストに追加する a = [1,2,3,4,5] print(a) a.append(6) a.append(7) a.append(8) print(a) |
【結果】
1 2 | [1, 2, 3, 4, 5] [1, 2, 3, 4, 5, 6, 7, 8] |
append()メソッドの後に出力された「変数a」には、「6,7,8」の値が追加されているのがわかります。
以下のように空のリストからfor文を使って要素を追加する方法もよく使いますので合わせて覚えておきましょう。。
1 2 3 4 5 6 7 8 9 10 11 | #リストに追加する #空ファイルを用意 d = [] print('dの初期状態 = ',d) for i in range(10): d.append(i) print('dの最終状態= ',d) |
【結果】
1 2 | dの初期状態 = [] dの最終状態= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
その他、リストにリストを追加する方法もあります。
1 2 3 4 5 6 7 8 | #リストにリストを追加する a = [1,2,3,4,5] b = [1,'kamakiri',32] a.append(b) print(a) |
【結果】
1 | [1, 2, 3, 4, 5, [1, 'kamakiri', 32]] |
※要素の追加の基本的なメソッドはappend()メソッドを使うのですが、この方法は計算時間がかかるためリストに要素を代入する方法は以下のようにする方が良いです。
試しに2通りの計算方法で計算時間を測定してみます。
- ふつうにappend()メソッドを使う場合
1 2 3 4 5 6 7 8 9 10 11 | #よく使うやり方(計算が遅い) import time a = [] start = time.time() for i in range(1,100000000): a.append(i) end = time.time()-start print(end) |
空の「変数a」というリストを用意して、for文で100000000回ループを回し、変数aに要素を追加していきます。
「start = time.time()」と「end = time.time()-start」で計算時間を計測するプログラムを仕込んで計算時間を測定して、print文で計算時間を出力しています。
【結果】
1 | 14.259172677993774 |
ループ数が多いので今回の計算では15秒かかっているのが確認できました。
- append()メソッドを使わないで要素を直接リストに代入する方法
※こちらの方が計算時間が早いです。
1 2 3 4 5 6 7 8 9 10 | #よく使うやり方(計算が早い) import time a = [] start = time.time() b = [i for i in range(1,100000000)] end = time.time()-start print(end) |
append()メソッドを使わずに、「i for i in range(1,100000000)」を直接リストの中に書いています。
【結果】
1 | 5.695846319198608 |
こちらの計算は「約5秒」です。
b = [i for i in range(100000000)]の書き方の方が計算が早いことがわかりますよね。
このように計算時間に違いが出たのは、appendの呼び出しに時間の違いです。
一つ目の方法では、for文の中でappend()メソッドを毎回呼び出しているため計算時間がかかってしまうというわけです。
※ちなみに余談ですが、Google colabなら冒頭に「%%time」とつけると計算時間を測定してくれます。
1 2 3 4 5 6 7 | #よく使うやり方 %%time a = [] b = [i for i in range(1,100000000)] |
【結果】
1 2 | CPU times: user 4.2 s, sys: 2.71 s, total: 6.91 s Wall time: 6.91 s |
※Google Colabでの別の計算時間測定方法として、冒頭に「%%timeit」とすると100000000回計算した平均時間を出力してくれますが、今回のようにループが多い場合はクラッシュするのでやめておきましょう!
リストに別のリストを追加➡extend()メソッド
extend()メソッドを使えば、リストに別のリストの要素を追加することができます。
※append()メソッドではリストもデータの塊としてそのまま追加されてしまいましたが、extend()メソッドはリスト内の要素を追加するというメソッドになります。
1 | リスト1.extend(リスト2) |
👆このように書くことで、「リスト1」に「リスト2」の要素を追加することができます。
では、実際にコードを書いてみます。
1 2 3 4 5 6 7 8 9 10 11 | #リストに追加する a = [1, 2, 3, 4, 5, 6, 7, 8,100] b = ['kamakiri', 'apple', '32'] print('a=',a) print('b=',b) #リストaにリストbを追加する a.extend(b) print('a=',a) |
【結果】
1 2 3 | a= [1, 2, 3, 4, 5, 6, 7, 8, 100] b= ['kamakiri', 'apple', '32'] a= [1, 2, 3, 4, 5, 6, 7, 8, 100, 'kamakiri', 'apple', '32'] |
「変数a」のリストに「変数b」のリストの要素が追加されたのが確認できます。
※実は、リストの要素の追加は以下のような演算を行うことで追加することができます。
1 2 3 4 5 6 7 | # リスト同士の演算 a = [1,2,3,4,5,6] b = ['kamakiri','apple',32] print(type(a)) print('足し算:' , a+b) |
【結果】
1 2 | <class 'list'> 足し算: [1, 2, 3, 4, 5, 6, 'kamakiri', 'apple', 32] |
リストの足し算は、リスト同士を足すことになります。
(結合させるイメージ)
※要素同士の演算をする場合はndarrayオブジェクトにする必要場あるので注意です。
1 2 3 4 5 6 7 8 9 10 11 12 13 | import numpy as np a = np.array( [1,2,3] ) b = np.array( [4,5,6] ) print(type(a)) print(type(b)) print(type(a+b)) print('足し算:' , a+b) |
【結果】
1 2 3 4 | <class 'numpy.ndarray'> <class 'numpy.ndarray'> <class 'numpy.ndarray'> 足し算: [5 7 9] |
この場合は、「変数a」のリストの要素数と、「変数b」のリストの要素数が異なるとエラーになるので、演算する要素数の数はお互い同じにしておく必要があります。
指定した位置に要素を追加➡insert()メソッド
insert()メソッドを使えば、任意の位置に要素を追加することができます。
1 | リスト.insert(インデックス, 追加する要素) |
実際にコードを書いてみます。
1 2 3 4 5 6 7 8 9 10 11 | #リストに追加する a = [1, 2, 3, 4, 5, 6, 7, 8,100] print('a=',a) #4番目の位置に追加 a.insert(3,'kamakiri') print('a=',a) |
【結果】
1 2 | a= [1, 2, 3, 4, 5, 6, 7, 8, 100] a= [1, 2, 3, 'kamakiri', 4, 5, 6, 7, 8, 100] |
インデックス3(リスト内の4番目の要素)に「’kamakiri’」という文字列の要素が追加されたのがわかります。
リスト内の要素の削除
リスト内の要素の削除には、以下の2つを覚えておきましょう。
- 要素の値を削除➡remove()メソッド
- 要素のインデックスを指定して値を削除➡pop()メソッド
- 要素の値を削除➡remove()メソッド
1 2 3 4 5 6 7 8 9 10 | #リストに追加する a = [1, 2, 3, 4, 5, 6, 7, 8,100] print(a) #要素内の値を指定 a.remove(100) print(a) |
要素内の値「100」を指定することで、要素を削除することができます。
【結果】
1 2 | [1, 2, 3, 4, 5, 6, 7, 8, 100] [1, 2, 3, 4, 5, 6, 7, 8] |
- 要素のインデックスを指定して値を削除➡pop()メソッド
1 2 3 4 5 6 7 8 9 10 | #リストに追加する a = [1, 2, 3, 4, 5, 6, 7, 8,100] print(a) #インデックスを指定 a.pop(3) print(a) |
【結果】
1 2 | [1, 2, 3, 4, 5, 6, 7, 8, 100] [1, 2, 3, 5, 6, 7, 8, 100] |
今回はインデックスを指定(3を指定)したので、対応するインデックスの要素が削除されています。
リストの更新
次にリスト内の要素を更新する方法についてみていきます。
リスト内の要素の値を更新する(別のデータに置き換える)方法はとても簡単です。
以下のように要素のインデックスを指定して値を代入するだけです。
1 | リスト[インデックス] = 更新するデータ |
では、実際にコードを書いてみます。
1 2 3 4 5 6 7 8 9 10 | #リストに追加する a = [1, 2, 3, 5, 6, 7, 8] print(a) #インデックスを指定 a[5] = 1000 print(a) |
インデックス5の要素の値(a[5]=7)を1000に更新して出力してみます。
【結果】
1 2 | [1, 2, 3, 5, 6, 7, 8] [1, 2, 3, 5, 6, 1000, 8] |
このようにa[5]の値が更新されているのがわかります。
その他リスト要素について調べる際に使うメソッド
リスト型はよく使うため、以下のメソッドも合わせて覚えておきましょう。
【ポイント】
- リストのインデックスを知りたい➡index()メソッド
- リスト内の要素の数を知りたい➡count()メソッド
- リストの要素数を知りたい➡len()関数
- リスト内の要素の並べ替え➡sort()メソッド
- リストの要素をコピーする➡copy()メソッド
※関数とメソッドは以下のように区別されます。- 単独で呼び出しできるのが「関数」(例:print()やlen() )
- 変数や値に付けて呼び出すのが「メソッド」(例:変数や値の後にドット(
.
)を付けて呼び出します。)
リストのインデックスを知りたい➡index()メソッド
リスト内の要素が何番目にあるのかを調べるためには、index()メソッドを使います。
1 | リスト.index(インデックスが知りたい要素の値) |
実際にコードを書いてみます。
1 2 3 4 5 | #index()メソッド list = ['商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B'] list.index('商品A') |
【結果】
1 | 1 |
結果は「1」という値が返ってきました。
これは、「’商品A’」という要素の値が1番目に存在するためです。
このように同じ要素の値が複数がある場合は、一番最初のインデックスを返してくれます。
では、「’商品A’」のみを取り出したい場合はどうすればよいのかというと、for文とif文を使ってリスト内の要素を判別しながら「’商品A’」のみを取り出せばよいです。
1 2 3 4 5 6 7 8 9 10 | #index()メソッド list = ['商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B'] list_A = [x for i, x in enumerate(list) if x == '商品A'] list_A_index = [i for i, x in enumerate(list) if x == '商品A'] print('商品Aが含まれる要素のみ取り出す➡',list_A) print('商品Aが含まれるインデックス➡',list_A_index) |
for文でenumerate(リストの変数)を使うと、インデックスと要素の値を同時に取り出しながらループを回すことになるため便利です。
【結果】
1 2 | 商品Aが含まれる要素のみ取り出す➡ ['商品A', '商品A', '商品A', '商品A', '商品A', '商品A'] 商品Aが含まれるインデックス➡ [1, 2, 6, 7, 11, 12] |
このように、「’商品A’」のみを取り出しながら、同時に「’商品A’」があったインデックスも取り出すことができます。
リスト内の要素の数を知りたい➡count()メソッド
「’商品A’」がリスト内に何個あるのかを数えるときは、count()メソッドを使います。
1 | リスト.count(数えたい要素) |
実際にコードを書いてみます。
1 2 3 4 5 6 | #count()メソッド list_A = ['商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B'] list_A.count('商品A') |
【結果】
1 | 6 |
「6」と返ってきました。
「’商品A’」が6個存在しているということになります。
リストの要素数を知りたい➡len()関数
リストのデータ量がどれだけあるのかを確認することがたまにあるのですが、そのときはlen()関数を使います。
1 | len(リスト) |
実際にコードを書いてみます。
1 2 3 4 5 | #len()メソッド list = ['商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B','商品B','商品A','商品A','商品C','商品B'] len(list) |
【結果】
1 | 15 |
結果が「15」と返ってきたので、list内の要素数は15個ということがわかります。
リスト内の要素の並べ替え➡sort()メソッド
sort()メソッドはPythonが標準で用意しているライブラリの関数です。
このメソッドは、リスト内の要素の比較のみを用いて要素の並べ替えを行うメソッドです。
sortは関数なので、引数を渡すことができるので()が必要です。 もちろん引数を渡さなくても良いです。
1 2 3 4 5 6 7 | # 順番を入れ替える a = [5,6,2,8,100] a.sort() print(a) |
【結果】
1 | [2, 5, 6, 8, 100] |
数字の順番を入れ替えるのはよくやることですよね。
例えば、商品の金額順の小さい順に並べ替えるなど・・・・
数字の小さい順に並び変えるのがデフォルトの設定ですが、反対に数字の大きい順に並べ替えることができます。
そのためには、sort()メソッドのオプションで「reverse=True」とすれば良いです。
1 2 3 4 5 6 7 | # 順番を入れ替える a = [5,6,2,8,100] a.sort(reverse=True) print(a) |
【結果】
1 | [100, 8, 6, 5, 2] |
※ここで注意として、「数値型」と「文字列」がリスト内の要素として混在している場合はsort()メソッドのデフォルト設定ではエラーが出てしまいます。
1 2 3 4 5 6 7 | # 順番を入れ替える(数値型と文字列が混在している) b = [1,'kamakiri',32] b.sort() print(b) |
【結果】
1 2 3 4 5 6 7 8 9 10 | --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-8-768fafca6416> in <module>() 3 b = [1,'kamakiri',32] 4 ----> 5 b.sort() 6 7 print(b) TypeError: '<' not supported between instances of 'str' and 'int' |
エラー内容を見ると、「’str’ and ‘int’」でエラーが出ていますよね。
これはリストの要素内での比較演算がうまくいかなかったときのエラーです(数値と文字の大小を比較できない)
以下のように、アルファベット順に並び替えることもできます。
1 2 3 4 5 6 7 | # 順番を入れ替える b = ['kamakiri', 'bird' , 'dog'] b.sort() print(b) |
【結果】
1 | ['bird', 'dog', 'kamakiri'] |
リストの要素をコピーする➡copy()メソッド
辞書の要素をコピーする方法は、copy()メソッドを使います。
※ここで、「=]で変数を定義する場合と何が違うのかを明確に理解しておく必要があります。
これは「参照渡し」と「値渡し」の違いを明確に理解しているかどうかが重要になりますので、以下の記事をお読みください<(_ _)>
- 参照渡し:「=」を使って値を代入した場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #参照渡し list_a = ['kamakiri',32,'male'] print('list_a=', list_a,type(list_a), id(list_a)) print('↓以下で変更を行う') #代入する list_b = list_a #インデックス0の値を変更 list_b[0] = 'apple' print('list_a=', list_a,type(list_a), id(list_a)) print('list_b=',list_b, type(list_b), id(list_b)) |
【結果】
1 2 3 4 | list_a= ['kamakiri', 32, 'male'] <class 'list'> 140327616736648 ↓以下で変更を行う list_a= ['apple', 32, 'male'] <class 'list'> 140327616736648 list_b= ['apple', 32, 'male'] <class 'list'> 140327616736648 |
「id」を使ってアドレスを確認してみるとすべて「140327617663176」となっているのがわかります。
これは「list_b = list_a」としたときに、「list_a」のアドレスごと「list_b」に代入しているのため、「list_b」の値を変更するということはアドレス内のデータごと変えているということになります。
そのため、「list_b[0] = ‘apple’」としたときに、「list_a」には何も操作をしていないのにその後の、print文で「list_a」のインデックス0の値も変更されてしまっているのがわかります。
これを、参照渡しといいます。
- 値渡し:.copy()メソッドを使ってコピーした場合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #値渡し list_a = ['kamakiri',32,'male'] print('list_a=', list_a,type(list_a), id(list_a)) print('↓以下で変更を行う') #代入する list_b = list_a.copy() #インデックス0の値を変更 list_b[0] = 'apple' print('list_a=', list_a,type(list_a), id(list_a)) print('list_b=',list_b, type(list_b), id(list_b)) |
【結果】
1 2 3 4 | list_a= ['kamakiri', 32, 'male'] <class 'list'> 140327617421384 ↓以下で変更を行う list_a= ['kamakiri', 32, 'male'] <class 'list'> 140327617421384 list_b= ['apple', 32, 'male'] <class 'list'> 140327616893128 |
先ほどの「参照渡し」での結果と異なるのがわかりますか。
「list_b[0] = ‘apple’」とした後でも、「list_a」には一切変更を受けていないのがわかりますね。
これは、「list_b = list_a.copy()」としたときに、違うアドレスに「list_b」が生成されているため、「list_a」と「list_b」は全く別のアドレスに値を持つようにできています。
なので、「list_b」をいくらいじろうとも、「list_a」には影響しないということになります。
※実際にidによってアドレスを確認すると、「list_a」と「list_b」は別のアドレスになっていますよね。
これを値渡しといいます。
まとめ
- Pythonのリスト型とは?
- リストの要素の取り出し
- リストの要素の追加・削除・更新の方法
要素を追加➡append()メソッド
リストに別のリストを追加➡extend()メソッド
指定した位置に要素を追加➡insert()メソッドリストの要素を削除
要素の値を削除➡remove()メソッド
要素のインデックスを指定して値を削除➡pop()メソッドリストの要素の更新(リストのインデックスを指定して値を入れ替える) - その他リスト型の関数とメソッド
リストのインデックスを知りたい➡index()メソッド
リスト内の要素の数を知りたい➡count()メソッド
リストの要素数を知りたい➡len()関数
リスト内の要素の並べ替え➡sort()メソッド
リストの要素をコピーする➡copy()メソッド
リスト型で使うメソッド(公式ドキュメント)としては以下のものがあるのでまとめておきます。
append | リストの末尾に要素を一つ追加 |
extend | リストに別のリストを追加 |
insert | 指定した位置に要素を追加 |
remove | 要素の値を削除 |
pop | 指定した位置に要素を追加 |
index | リストのインデックスを知りたい |
count | リスト内の要素の数を知りたい |
sort | リスト内の要素の並べ替え |
copy | リストの要素をコピーする |
clear | リスト中の全ての要素を削除 |
reverse | リストの要素を、インプレース演算で逆順にします。 |