Pythonで扱うデータ型の中にリスト型があります。
リスト型は、数値や文字列などのデータが配列として並んだデータ型のことをいいます。
データベースから必要な部分を抽出した場合やある画像の処理・解析を行なう場合など、多岐に渡り使用されるため、リスト操作を行なう機会は多いかと思います。
この記事では、データ処理を行なう際によく使われるリスト操作について説明します。
さらに詳細を知りたい方は、「3. An Informal Introduction to Python > 3.1. Using Python as a Calculator > 3.1.3. Lists」や「5. Data Structures > 5.1. More on Lists」などを参照ください。(日本語に翻訳されているので、英語が苦手な方でも大丈夫です、多分)
要素の追加
以下の手法は、リスト内へデータを追加する機能を持っています。
※リスト操作に限った話ではありませんが、各手法が扱えるデータ型には制限や決まりがあるため、それらに注意してください。
append(x)
list.append(x)という手法は、リストの最後尾にデータ(x)を追加する機能を有します。
list = [1, 2, 3] num = 4 list.append(num) print(list) # 出力結果 >>> [1, 2, 3, 4]
この手法により追加されたデータ(x)は、1つの要素として扱われます。
よって、以下のようにリストを追加した場合は、リスト自体を1つの要素として追加します。
list_1 = [1, 2, 3] list_2 = [4, 5] list_1.append(list_2) print(list_1) # 出力結果 >>> [1, 2, 3, [4, 5]]
数値に限らず、"A" や "a" といったアルファベットも、"Thank you" といった文字列も1つの要素として追加されます。
extend(iterable)
list.extend(iterable)という手法は、イテラブルの全要素をリストに追加する機能を有します。イテラブルとは、リスト:[1, 2, 3] やタプル:(1, 2, 3) 、文字列:"Thank you" といったデータの集まりのことをいいます。
list_1 = [1, 2, 3] list_2 = [4, 5] string = "Thank you" list_1.extend(list_2) print(list_1) # 出力結果 >>> [1, 2, 3, 4, 5] list_2.extend(string) print(list_2) # 出力結果 >>> [4, 5, "T", "h", "a", "n", "k", " ", "y", "o", "u"]
この手法では、データの集合を各要素に分解してリストに追加します。
そのため、リストや文字列は上記コードのように分解されます。
ただし、以下のような単体の数値はこの手法で追加することはできません。
list = [1, 2, 3] num = 4 list.extend(num) # 出力結果 >>> TypeError: 'int' object is not iterable
insert(i, x)
list.insert(i, x)という手法は、データ(x)をリスト内の任意の場所(i)に追加する機能を有します。
list = [1, 2, 3, 4, 5] num = 99 list.insert(1, num) print(list) # 出力結果 >>> [1, 99, 2, 3, 4, 5, 6] list.insert(100, num) print(list) # 出力結果 >>> [1, 99, 2, 3, 4, 5, 6, 99]
この手法では、list.append(x)と同じように、追加するデータ(x)を1つの要素として追加します。
また、指定する場所(i)にはリスト内の最初の要素を0番目とした番号を入力します。
追加する場所(i)をリストの範囲外にした場合、データ(x)はリストの最後尾に追加されます。
追加する場所(i)をマイナスの値にした場合は、後述する list[start : end] の手法と同様に最後尾から数えた場所へ追加されます。
list_1 = [1, 2, 3] list_2 = [4, 5] list_1.insert(1, list_2) print(list_1) # 出力結果 >>> [1, [4, 5], 2, 3]
リストや文字列をこの手法で追加すると、list.append(x)と同様にそのデータ全てを1つの要素として追加します。
リスト内の調査
以下の手法は、リスト内全体や各要素の情報を取得または抽出するための機能を持っています。
list[start : end]
list[start : end] という手法は、リスト内の場所①(start)から場所②(end)までの要素をリスト型のデータで出力させる機能を有します。
list = [1, 22, 333, 4444, 55555, 666666] list[2:] # 出力結果 >>> [333, 4444, 55555, 666666] list[:3] # 出力結果 >>> [1, 22, 333] list[-1:] # 出力結果 >>> [666666] list[:-2] # 出力結果 >>> [1, 22, 333, 4444] list[1:-2] # 出力結果 >>> [22, 333, 4444] list[99:] # 出力結果 >>> [] list[:99] # 出力結果 >>> [1, 22, 333, 4444, 55555, 666666]
この手法では、指定した場所「から」または指定した場所「まで」の要素をリスト型で出力します。場所の値はマイナスでも指定可能です。
マイナスの場合、リスト内の最後尾を「-1」、その前を「-2」と右から数えてマイナスの数を増やしていくことで指定できます。
リストの範囲外の場所を start にした場合は空のリストが出力され、end にした場合は全要素が出力されます。
index(x, start, end)
list.index(x, start, end)という手法は、リスト内から指定したデータ(x)と同値の要素が場所①(start)から場所②(end)の区間内においてどこに位置するかを出力します。
list = [1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 5] # len(list) >>> 11 list.index(2) # 出力結果 >>> 2 list.index(2, 5) # 出力結果 >>> 8 list.index(1, 8, 10) # 出力結果 >>> 9 list.index(4) # 出力結果 >>> ValueError: 4 is not in list
引数の start と end は任意で指定できます。指定する際は、リスト内の最初の要素を0番目とした番号を渡します。
リストに無いデータ(x)を引数として渡すと、エラーが発生します。
count(x)
list.count(x)という手法は、指定したデータ(x)と同値の要素がリスト内に何個あるかを出力します。
list = [1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 5] list.count(1) # 出力結果 >>> 7 list.count(3) # 出力結果 >>> 1 list.count(4) # 出力結果 >>> 0
この手法は、データ(x)と同値の要素数をリスト内の全要素を対象にカウントしてくれます。リストに無いデータ(x)を指定した場合、エラーではなく0個と出力されます。この特徴は、関数内に組み込む際にも使い勝手の良い特徴かと思います。
sort(key=None, reverse=False)
list.sort(key=None, reverse=False)という手法は、リスト内の要素を(デフォルトの場合は)昇順に並び替える機能を有します。引数(key, reverse)を指定することで、並び替える方法を変更できます。
list_1 = [30, 10, 60, 20, 80, 40] list_2 = list_1 list_1.sort() # 出力結果 >>> [10, 20, 30, 40, 60, 80] list_2.sort(reverse=True) # 出力結果 >>> [80, 60, 40, 30, 20, 10]
この手法で引数を何も指定しない場合、リスト内を昇順に並び替えます。逆に、リスト内を降順に並び替える場合は、引数:reverse に True を渡します。
import operator list_1 = [[100, 200, 300], [200, 300, 100], [300, 100, 200]] list_2 = list_1 list_1.sort(key=operator.itemgetter(1)) # 出力結果 >>> [[300, 100, 200], [100, 200, 300], [200, 300, 100]] list_2.sort(key=lambda x: x[1]) # 出力結果 >>> [[300, 100, 200], [100, 200, 300], [200, 300, 100]]
引数:key には、並び替える際の条件を指定できる関数を渡します。
上記コードで記述した「operator.itemgetter(1)」と「lambda x: x[1]」はどちらも、各要素内の2番目を対象にして並び替える、という条件を表しています。
それを踏まえて出力結果を見ると、各要素の2番目の値が昇順で並ぶように出力されているのがわかると思います。
これは数値だけでなく、文字列についても同様に処理されます。
reverse()
list.reverse()という手法は、リスト内の要素を逆順に並び替える機能を有します。
list = [50, 10, 30, 70, 20] list.reverse() # 出力結果 >>> [20, 70, 30, 10, 50]
list.sort()の引数にも reverse があったかと思います。逆順に並び替えるという点では同じですが、こちらの手法を使った場合は昇順・降順への並び替えは行われません。単にリスト内の要素を逆順で並び替える手法になります。
要素の削除
以下の手法は、リスト内の全要素や指定した要素を削除する機能を持っています。
remove(x)
list.remove(x)という手法は、指定したデータ(x)と同値の要素を削除する機能を有します。
また、同値の要素が複数ある場合、最初の要素だけが削除されます。
list = [1, 3, 5, 7, 11, 11, 13] list.remove(11) print(list) # 出力結果 >>> [1, 3, 5, 7, 11, 13] list.remove(12) # 出力結果 >>> ValueError: list.remove(x): x not in list
削除したいデータ(x)がリスト内に複数ある場合は、for文・list.count(x) などと組み合わせることで対処できます。
指定したデータ(x)がリスト内に無かった場合は、エラーが発生します。
pop(i)
list.pop(i)という手法は、リスト内の指定した場所(i)に位置する要素を出力して削除する機能を有します。
また、場所(i)を指定しない場合は最後尾の要素を出力して削除します。
そして、リストの範囲外の場所を指定した場合、エラーが発生します。
list = [1, 3, 5, 7, 11, 13, 17] list.pop(2) # 出力結果 >>> 5 print(list) # 出力結果 >>> [1, 3, 7, 11, 13, 17] list.pop() # 出力結果 >>> 17 print(list) # 出力結果 >>> [1, 3, 7, 11, 13] list.pop(99) # 出力結果 >>> IndexError: pop index out of range
list.pop(i) の特徴は、実行した際に削除した要素を出力するところです。リストのどこから何を削除したのかがわかるため、確率の問題やゲーム開発などの場面で使われることが多いように思います。
clear()
list.clear()という手法は、リスト内の全要素を削除する機能を有します。
list = [1, 2, 3, 4, 5] list.clear() print(list) # 出力結果 >>> []
この手法の全要素を削除するという特徴は、ループ処理を行なう際にリスト内の要素数が任意の値を超えた場合に使うことで、実行プログラムの重さやメモリへの負担を減らすことができると思われます。
番外編:リスト内包表記
こちらはリストの作成方法になりますが、番外編として説明します。
[i for i in iterable if 条件式]
リスト内包表記とは、リスト作成においてfor文やif文といった複数行の記述が必要な処理を、角括弧内にまとめて記述することができる手法です。
list_1 = [i for i in range(0, 11)] print(list_1) # 出力結果 >>> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list_2 = [i for i in range(0, 11) if i > 5] print(list_2) # 出力結果 >>> [6, 7, 8, 9, 10]
この手法で複雑な処理を行なうことは難しいですが、簡単な条件に当てはめたデータを作りたい場合やプログラムを仮の条件で実行したい場合に、1行で迅速にリスト作成が行えるため使えるようになると何かと便利です。
まとめ
この記事では、データ処理を行なう際によく使われるリスト操作について説明しました。
近年では、AIやIoTなどのデータサイエンスの分野にPythonが使われていることが多々あります。技術者や職人たちの減少により、AIが必要とされる一方で、そのAIを作る技術者も必要とされています。
Pythonを使う人口は更に増えていくだろうと思いますし、増えてほしいと思っています。
既にPythonを使っている方、これから学習する方、皆さんの目的を達成するために色々な使い方をしてみてください。そして、その中の誰かが共有して、どんどん新しい使い方が増えて、と考えるとワクワクしてきます。
私もできる限り、誰にでもわかりやすい形で説明・紹介・共有したいと思っていますので、今後ともよろしくお願いします。