こんにちは。
list(リスト)の使い方の前編の記事でリストの基本的な使い方、リストのデータの操作方法について習得しました。
前編の記事については以下を参考にして下さい。
【Python入門】list(リスト)の使い方の総まとめ【前編】
続きを見る
本記事での後編では、もう少し深掘りして使いこなせるようにしていきましょう。
本記事での学習内容
- 検索
- 並び替え
- 内包表記
- アンパック
では早速、学習していきましょう。
list(リスト)の「検索」としての使い方
リストではその中に、対象が含まれるか?何個あるか?などを調べることができるメソッドがあります。
以下にリストの検索としての使い方として「対象が含まれるか」「何個あるのか」を調べるために有用なメソッドをまとめておきます。
リストの検索の方法として用いるメソッド
- in(検索対象が含まれるかどうかを調べるメソッド)
- not in(検索対象が含まれていないかどうかを調べるメソッド)
- index (リスト内のデータの位置を確認)
in (含まれるかどうかを調べるメソッド)
リストに検索対象が含まれているかどうかを調べることができます。
返り値が True
または False
なので、if
文などで、リストに**が含まれていれば、この処理をするといった使い方をすることが多いです。
inメソッドの記述のルール
- 検索対象 in リスト
数値と文字列も確認したほうがわかりやすいので、確認してみましょう。
In[]
1 2 3 4 | # 数値 list_num = [1, 2, 3, 4] print(1 in list_num) # 数値が含まれる print(5 in list_num) # 数値が含まれない |
Out[]
1 2 | True False |
In[]
1 2 3 4 | # 文字列 list_str = ['cat', 'dog', 'hippo', 'pig'] print('cat' in list_str) # 文字が含まれている print('human' in list_str) # 文字が含まれていない |
Out[]
1 2 | True False |
not in(含まれないか)
not in はリストに含まれていない場合にTrueを返すので、 inの時と逆の返り値を返します。
not inメソッドの記述ルール
- 検索対象 not in リスト
こちらも in
の時と同様、数値と文字列で確認してみましょう。
In[]
1 2 3 4 | # 数値 list_num = [1, 2, 3, 4] print(1 not in list_num) # 数値が含まれる print(5 not in list_num) # 数値が含まれない |
Out[]
1 2 | False True |
In[]
1 2 3 4 | # 文字列 list_str = ['cat', 'dog', 'hippo', 'pig'] print('cat' not in list_str) # 文字が含まれている print('human' not in list_str) # 文字が含まれていない |
Out[]
1 2 | False True |
index(リスト内の位置を確認するメソッド)
indexメソッドを使用することで、リストの内のデータが何番目にあるかを調べることができます。
要素Noを調べるので、返り値は 0〜 の数値が返ってきます。
index メソッドの記述のルール
- リスト.index(検索対象)
数値と文字列で、実際に確認してみましょう。
In[]
1 2 3 | # 数値 list_num = [1, 2, 3, 4] print(list_num.index(3)) # 3の要素No |
Out[]
1 | 2 |
In[]
1 2 3 | # 文字列 list_str = ['cat', 'dog', 'hippo', 'pig'] print(list_str.index('dog')) # dogの要素No |
Out[]
1 | 1 |
index メソッドの注意のポイント
この index メソッドは、リスト内に複数ある場合でも、1つの要素Noしか返してくれません。
例えば、list_str
に’ cat
’が二つ入っている場合、要素Noの「0」と「4」が欲しいところですが、動かしてみると「0」しか返ってきません。
In[]
1 2 | list_str = ['cat', 'dog', 'hippo', 'pig', 'cat'] print(list_str.index('cat')) # catの数検索 |
Out[]
1 |
複数の要素Noがほしい場合には、後で説明する内包表記を使うと便利です。
count(含まれている数をカウントするメソッド)
count
メソッドは検索した対象がリスト内に何個含まれているかを検索することができる機能です。
count メソッドの記述ルール
- リスト[要素No]
これも、 数値と文字列で確認してみましょう。
In[]
1 2 3 4 | # 数値 list_num = [1, 2, 3, 4, 2] print(list_num.count(1)) # 1の数検索 print(list_num.count(2)) # 2の数検索 |
Out[]
1 2 | 1 2 |
In[]
1 2 3 4 | # 文字列 list_str = ['cat', 'dog', 'hippo', 'pig', 'cat'] print(list_str.count('dog')) # dogの数検索 print(list_str.count('cat')) # catの数検索 |
Out[]
1 2 | 1 2 |
単調になりますが、コツコツ修得していきましょう。
具体的な使い道は最後にある課題を参考にしていただけると、より理解が深まります。
list(リスト)の「並び替え」としての使い方
配列を取り扱っていると、当然並び替えが必要になります。
例えば、リスト内に含まれている数が「多い・少ない」や「ファイル名の並び替え」です。
以下にリストの並び替えを行う事ができるメソッドをまとめます。
list(リスト)の並び替えとして有用なメソッド
- sort
- sorted関数
- 2次元のリストのソート
sortの使い方
sort メソッドはリストの中身を並び替えることができます。
sort の記述ルール
- リスト.sort()
In[]
1 2 3 4 | list_num = [1,5,3,0,2,4] print(list_num) #並び替え前 list_num.sort() print(list_num) #並び替え後 |
Out[]
1 2 | [1, 5, 3, 0, 2, 4] [0, 1, 2, 3, 4, 5] |
sorted関数
sort
はリストのメソッドなのでリストでしか使用できませんが、sorted関数はリスト以外にも使えるのでこちらも覚えておきましょう。
sorted関数の記述ルール
- sorted(イテラブル)
ここで、イテラブルについての解説です。
イテラブルについて
sorted
(イテラブル)とは、リスト、タプル、rangeなどの繰り返し処理できるオブジェクトです。
ここで、注意すべきポイントがあるのでおさえておきましょう。
注意ポイント
sorted
を実行したら、並び替えられたものが返り値として得られるのでそれを変数に代入する必要があります。
以下のコードを参照にして下さい。
In[]
1 2 3 4 | # sorted関数を実行しただけではlist_numの中身は並び替えされない list_num = [1,5,3,0,2,4] sorted(list_num) print(list_num) |
Out[]
1 | [1, 5, 3, 0, 2, 4] |
In[]
1 2 3 4 | # sorted()の返り値を list_numか新しく定義した変数に入れる必要がある。 list_num = [1,5,3,0,2,4] list_num = sorted(list_num) print(list_num) |
Out[]
1 | [0, 1, 2, 3, 4, 5] |
2次元のリストのソート
CSVのような表データを取り扱う場合は、2次元のリストのソートもする必要があります。
そんな時は、メソッドの引数に key
というのがあるので、key
に無名関数を渡してあげると実現できます。
無名関数の記述の方法
- lambda 引数: 処理
下記に普通の関数と比較しておきます。普通の関数を1行で書いているイメージです。
In[]
1 2 3 4 5 6 | # 普通の関数 def func(引数): return 処理 # 無名関数 lambda 引数:処理 |
今回は後で課題でも使う 商品リスト(販売日、商品ID、商品名、個数、金額) についてソートしてみます。
In[]
1 2 3 4 5 6 | list_product = [['20200219', '4', 'アメ' , 1, 100], ['20200120', '3', 'ガム' , 1, 80], ['20200301', '5', 'ポッキー' , 2, 120], ['20200320', '1', 'グミ' , 1, 100], ['20200220', '5', 'ポッキー', 3, 120], ['20200104', '2', 'ポテチ', 2, 100]] |
先に無名関数の動作を確認してみましょう。
まず、list_product
から商品IDを取得する無名関数を宣言します。
In[]
1 2 3 4 5 6 7 8 | # 引数がproductで例えば、['20200120', '3', 'ガム' , 1, 80]とか # 返り値がproduct[1]で'3'になります。 func = lambda product:product[1] # 1つの商品で確認 print(func(list_product[1])) # 複数の商品で確認 list_new_num = [func(i) for i in list_product] list_new_num |
Out[]
1 2 | 3 ['4', '3', '5', '1', '5', '2'] |
商品IDが取得できましたね。
この無名関数を key
に渡すことで、「商品ID」をソートできるようになります。
In[]
1 2 | list_product.sort(key=lambda product:product[1]) list_product |
Out[]
1 2 3 4 5 6 | [['20200320', '1', 'グミ', 1, 100], ['20200104', '2', 'ポテチ', 2, 100], ['20200120', '3', 'ガム', 1, 80], ['20200219', '4', 'アメ', 1, 100], ['20200301', '5', 'ポッキー', 2, 120], ['20200220', '5', 'ポッキー', 3, 120]] |
コードの補足をしていきます。
In[]
1 | lambda product:product[1] |
無名関数の引数にしている productは[ 販売日、商品ID、商品名、個数、金額 ]
を指していて、処理のところの product[1]
は要素No1をしているので商品IDを指しています。
なので、このソートは商品IDをソートしますという処理になります。
変数名を product
としていますが「p
」でも「prod
」でもなんでもよいです。
print
使わないほうがわかりやすく表示されたので、今回は print
を使わず、list_product
を表示しています。
reverse の使い方
リストを反転したい場合に使用します。
例えば、数字を sort
で小さいほうから並び替えるのではなく、大きいほうから並び変える場合です。
reverseの記述のルール
- リスト.reverse()
list_num
をソートした後、reverse
で反転させてみます。
In[]
1 2 3 4 5 | list_num = [1,5,3,0,2,4] list_num = sorted(list_num) print(list_num) #並び替え後 list_num.reverse() print(list_num) #反転後 |
Out[]
1 2 | [0, 1, 2, 3, 4, 5] [5, 4, 3, 2, 1, 0] |
reverse
メソッドでも可能ですが、行数が多くなります。
そのため、下記のように、sort
、sorted
に reverse = True
の引数を渡しても同じことが実現できます。
In[]
1 2 | list_num.sort(reverse=True) list_num = sorted(list_num, reverse=True) |
reverse
は pop
メソッドを使うときにも使うことがあります。
pop
はリストの末尾から順番に削除して取得します。
ですので、この取得順番を逆にしたい場合は reverse
で反転するとよいでしょう
下記は並び替えて0~5のリストにした後、pop
で松木から「5」「4」と値を取り出します。
In[]
1 2 3 4 | list_num = [1,5,3,0,2,4] list_num = sorted(list_num) #並び替え print(list_num.pop()) #popで末尾から取得 print(list_num.pop()) |
Out[]
1 2 | 5 4 |
次に reverse
を使って5~0のリストにして、pop
で末尾から「0」「1」と値を取り出します。
In[]
1 2 3 4 | list_num = [1,5,3,0,2,4] list_num = sorted(list_num, reverse=True) #並び替え print(list_num.pop()) #popで末尾から取得 print(list_num.pop()) |
Out[]
1 2 | 0 1 |
list(リスト)の内包表記について
内包表記はfor文で複数行で書くのをシンプルに1行で書いてしまう方法です。
1行ですっきりするというのもありますが、処理が内包表記のほうが早い利点があります。
まず、通常の for
文の書き方と内包表記で比較してみましょう。
通常のfor文でも、if文の条件や処理部がない場合があると思いますが、内包表記でも同じです。
for文なのでリスト以外のイテラブル(タプル、range等)も同じように取り扱うことができます。
list(リスト)の基本的な使い方
条件も処理もしない場合の基本的な書き方から習得していきます。
リストの基本的な記述のルール
- [変数名 for 変数名 in リスト]
練習として、list_num
を list_new
にそのまま入れてみましょう。
In[]
1 2 3 | list_num = [1,5,3,0,2,4] list_new = [i for i in list_num] print(list_new) |
Out[]
1 | [1, 5, 3, 0, 2, 4] |
リストにif文の追加の仕方
次にif文を追加してみましょう。
if文の記述する際のルール
- [変数名 for 変数名 in リスト if 条件]
条件はシンプルに偶数のみを取得するようにします。
処理イメージがわからなくなったら、通常のfor文と比較して確認してください。
In[]
1 2 3 | list_num = [1,5,3,0,2,4] list_new = [i for i in list_num if i%2 == 0] print(list_new) |
Out[]
1 | [0, 2, 4] |
リスト(list)で処理を追加する方法
最後に変数に対する処理も追加しましょう。
処理を追加する際の記述ルール
- [処理(変数名) for 変数名 in リスト if 条件]
処理を追加する場合、関数を使ってもよいですし、1行で済む処理ならそのまま処理を記述します。
ここもシンプルしましょう。変数を2乗する処理を追加します。
In[]
1 2 3 | list_num = [1,5,3,0,2,4] list_new = [i**2 for i in list_num] print(list_new) |
Out[]
1 | [1, 25, 9, 0, 4, 16] |
indexの複数化
リストのindexは複数該当するものがあっても、1つしか返してくれないという話をしました。
その場合の実現方法に内包表記があり、下記がコード例になります。
enumerate
という関数を使いますが、これは要素Noとリストの値を同時に取得するもので、リストの値を if
文で判定しながら、一致する要素Noを list_new
に渡します。
In[]
1 2 3 | list_str = ['cat', 'dog', 'hippo', 'pig', 'cat'] list_new = [i for i, obj in enumerate(list_str) if obj == 'cat'] print(list_new) |
Out[]
1 | [0, 4] |
アンパック
リストを使っているとアンパックという方法を高頻度で使用します。
アンパックの記述のルール
- 変数1, 変数2, ..変数n = リスト
仕組みは単純で、リスト内のデータを変数に分けて入れることができます。
犬の情報が1つ入ったリストで考えてみます。名前、犬種、体重が入ったリストから各変数にアンパックして、表示します。
In[]
1 2 3 4 | # 名前、犬種、体重のリスト list_dog = ['ポチ', '柴犬', 10] name, breed, weight = list_dog # アンパック print(name, breed, weight) |
Out[]
1 | ポチ 柴犬 10 |
このアンパックはfor文とも併用するので、下記コードでも動作確認してみてください。
アンパックしながら、for文で値を取り出すことができます。
In[]
1 2 3 4 5 | list_dog_list = [['ポチ', '柴犬', 10], ['レオ', 'ブルドック', 15],] # アンパックしながら取り出す for name, breed, weight in list_dog_list: print(name, breed, weight) |
Out[]
1 2 | ポチ 柴犬 10 レオ ブルドック 15 |
取得の必要が無い項目はアンダーバー「_」で省略が可能です。
In[]
1 2 3 4 5 | list_dog_list = [['ポチ', '柴犬', 10], ['レオ', 'ブルドック', 15],] # アンパックしながら取り出す for name, _, weight in list_dog_list: print(name, weight) |
Out[]
1 2 | ポチ 10 レオ 15 |
リスト(list)の課題
商品リスト(販売日、商品ID、商品名、個数、金額)を使って、「検索」「並べ替え」「集計」を実施
仕様
その①:変数名list_productで下記表をリストにしてください。
※ 商品IDは文字列、数値でもよいです
販売日 | 商品ID | 商品名 | 個数 | 金額 |
20200219 | 4 | アメ | 1 | 100 |
20200120 | 3 | ガム | 1 | 80 |
20200301 | 5 | ポッキー | 2 | 120 |
20200320 | 1 | グミ | 1 | 100 |
20200220 | 5 | ポッキー | 3 | 120 |
20200104 | 2 | ポテチ | 2 | 100 |
以下の流れに沿って、作成していきましょう。
- 商品名で並び替えて表示
- 販売日で並び替えて表示
- 個数×金額の合計金額で並び替え
- 内包表記、アンパックを使って、商品名のリストを作成し、ポッキーの購入件数を表示
- 内包表記、アンパックを使って、ポッキーの購入日をリストで取得
- 内包表記、アンパックを使って、ポッキーの個数×金額=合計金額を算出
演習方法1
課題と仕様を見て、自身でコーディングしてみてください。
コーディングに不安な方は、演習方法2のコードの穴埋めにて演習を実施してください。
演習方法2
— コード追加 —に1行ずつコードを埋めていって、プログラムを完成させてください。
演習のJupyter notebookをご利用される方は演習(google driveリンク)を参照いただければと思います。
その①:変数名list_productで下記表をリストにしてください。
コード追加不要です。下記リストを使ってください。
In[]
1 2 3 4 5 6 7 | # 商品リスト list_product = [['20200219', '4', 'アメ' , 1, 100], ['20200120', '3', 'ガム' , 1, 80], ['20200301', '5', 'ポッキー' , 2, 120], ['20200320', '1', 'グミ' , 1, 100], ['20200220', '5', 'ポッキー', 3, 120], ['20200104', '2', 'ポテチ', 2, 100]] |
その②:商品名で並び替えて表示
In[]
1 2 | list_product.sort(--- コード追加 ---) list_product |
その③:販売日で並び替えて表示
In[]
1 2 | list_product.sort(--- コード追加 ---) list_product |
その④:個数×金額の合計金額で並び替え
In[]
1 2 | list_product.sort(--- コード追加 ---) list_product |
その⑤:内包表記、アンパックを使って、商品名のリストを作成し、ポッキーの購入件数を表示
In[]
1 2 | pname_list = --- コード追加 --- pname_list.count('ポッキー') |
その⑥:内包表記、アンパックを使って、ポッキーの購入日をリストで取得
In[]
1 2 | pocky_date = --- コード追加 --- pocky_date |
その⑦:内包表記、アンパックを使って、ポッキーの個数×金額=合計金額を算出
In[]
1 2 | pocky_sum = sum(--- コード追加 ---) pocky_sum |
解答
解答例(google driveリンク)を参照いただければと思います。
その⓪:変数名list_product で下記表をリストにしてください。
In[]
1 2 3 4 5 6 7 | # 商品リスト list_product = [['20200219', '4', 'アメ' , 1, 100], ['20200120', '3', 'ガム' , 1, 80], ['20200301', '5', 'ポッキー' , 2, 120], ['20200320', '1', 'グミ' , 1, 100], ['20200220', '5', 'ポッキー', 3, 120], ['20200104', '2', 'ポテチ', 2, 100]] |
その①:商品名で並び替えて表示
In[]
1 2 | list_product.sort(key=lambda product:product[2]) list_product |
その②:販売日で並び替えて表示
In[]
1 2 | list_product.sort(key=lambda product:product[0]) list_product |
その③:個数×金額の合計金額で並び替え
In[]
1 2 | list_product.sort(key=lambda product:product[3]*product[4]) list_product |
その④:内包表記、アンパックを使って、商品名のリストを作成し、ポッキーの購入件数を表示
In[]
1 2 | pname_list = [p_name for _, _, p_name, _, _ in list_product] pname_list.count('ポッキー') |
その⑤:内包表記、アンパックを使って、ポッキーの購入日をリストで取得
In[]
1 2 | pocky_date = [p_date for p_date, _, p_name, _, _ in list_product if p_name == 'ポッキー'] pocky_date |
その⑥:内包表記、アンパックを使って、ポッキーの個数×金額=合計金額を算出
In[]
1 2 | pocky_sum = sum([p_num*p_price for _, _, p_name, p_num, p_price in list_product if p_name == 'ポッキー']) pocky_sum |
以上2回にわたってlist(リスト)の使い方について学習しました。
list(リスト)の使い方の前編を復習する方は以下の記事を参考にしてください。
【Python入門】list(リスト)の使い方の総まとめ【前編】
続きを見る
補足|実際にあった質問
質問1
質問内容
課題に関して。
# 100回繰り返すfor文で list_hundred
を pop()
を使って、値を取り出しつつ、sum_all
に足してください。の箇所のコードの質問。
1 2 3 4 5 6 | sum_all = 0 for i in range(len(list_hundred)): sum_all += list_hundred.pop() print(sum_all) print(list_hundred) |
この箇所で、最後の print(list_hundred)
でなぜ []
が出力されるのかよく理解できなかった(以下画像)
回答
[]
はPop
の動作確認になります。
Pop
は取り出す事を意味するので、「値の取得と削除がされるんですよ」ということを意味します。
偶数、奇数時の足し算と動作が違っていることを確認しています。その為最後は []
が出力されます。
質問2
質問内容
1 2 | list_product.sort(key=lambda product:product[1]) list_product |
上記における、keyが期待している型は、list型でなく、文字型や数値型、というイメージであってますか?
この認識で、
1 2 3 | def getColNum(list_product): return list_product[0]list_product.sort(key = getColNum(i) for i in list_product) list_product |
というコードを書くと、SyntaxError
が発生したので、書き方として誤っているのかと考えています。
つまり、
list_product.sort(key=lambda product:product[1])`
sort
メソッドの key
が求めている型と、sort
メソッドへ渡された値(上記でいう product
)がどのように連動しているのかを教えて下さい。
おそらく一般的には、やらないと思うのですが、あえて関数で書こうとした際、どのように書くのかと疑問に思い実装したのですが、少し理解できていない点が上記となります。
回答
key
が期待しているのは関数です。なので、無名関数を使っていますが、普通の関数でも行けます。
公式ドキュメントを抜粋すると
「これは比較を行う前にリストの各要素に対して呼び出される関数を指定するパラメータです。」
最初は確かに、わかりにくい点ですが、「リストの各要素に対して呼び出される関数」となっているので、
関数の引数にはリストの「各要素」が割り当てられて、その返り値を並び替えで使いますよということです。
今回の返り値は各要素である商品リストの商品IDということになります。
ちなみに、通常の関数を使ったコードは下記です。無名関数の方が、行数が少ないですね。
関数には、処理が実行されているのがわかるようにprint入れています。
1 2 3 4 5 6 7 8 9 | list_product = [['20200219', '4', 'アメ' , 1, 100], ['20200120', '3', 'ガム' , 1, 80], ['20200301', '5', 'ポッキー' , 2, 120], ['20200320', '1', 'グミ' , 1, 100], ['20200220', '5', 'ポッキー', 3, 120], ['20200104', '2', 'ポテチ', 2, 100]]def sort_func(product): print('from sort_func', product[1]) return product[1]list_product.sort(key=sort_func) list_product |
今回は以上となります。お疲れ様でした。