1: 2016-12-04 (日) 08:58:28 njf |
現: 2016-12-04 (日) 19:59:46 njf |
| + | *内包表記と高階関数 [#c78e816b] |
| + | |
| + | Pythonではリストを変換する手段としてリスト内包表記を使う方法と、map、filterなどの関数を引数とする、高階関数を使う方法があります。 |
| + | |
| + | 一般に内包表記の方が高速で動作すると言われていて、公式でも内包表記が推奨されています。 |
| + | |
| + | とはいえ、他の言語でmapやfilterなどの高階関数を使ったことがある場合は、こちらのほうがわかりやすいでしょう。 |
| + | ここではなるべく両方のやり方を書いていきます。 |
| + | |
| + | |
| *要素の存在チェック [#qbf1fa46] | | *要素の存在チェック [#qbf1fa46] |
| + | |
| + | Pythonで特定の要素が存在するかは、「in」を用います。 |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | if 1 in testList: |
| + | print "1 exists!" |
| + | |
| + | if 10 in testList: |
| + | print "10 exists!" |
| + | |
| + | 結果 |
| + | |
| + | 1 exists! |
| + | |
| + | *要素を検索して場所を返す [#b64e62fd] |
| + | |
| + | 要素に特定の値が現れる場所を求めるには、indexを使います。 |
| + | 第二引数を省略すると最初の場所が返ります。 |
| + | |
| + | testList = [2,1,3,1,5,6] |
| + | |
| + | print testList.index(1) |
| + | |
| + | 結果 |
| + | 1 |
| + | |
| + | indexの第二引数、第三引数に整数を入れると、その区間にある要素の最初の場所が返ります。第三引数を省略するとリストの最後まで指定したことになります。 |
| + | |
| + | testList = [2,1,3,1,5,6] |
| + | |
| + | print testList.index(1,2,5) |
| + | |
| + | 結果 |
| + | 3 |
| + | |
| + | 要素がないとValueErrorが発生します。 |
| + | |
| + | 検索して一致した全ての場所を取り出すのは、以下のように内包表記を使うと簡単にできます。 |
| + | |
| + | resultList = [i for (i,x) in enumerate(testList) if x == 1 ] |
| + | |
| + | 結果 |
| + | [1, 3] |
| + | |
| + | enumerateは、インデックスと要素のタプルを返す関数です。 |
| + | |
| *検索した要素をリストで取得 [#q0d80e3c] | | *検索した要素をリストで取得 [#q0d80e3c] |
| + | |
| + | 例として3以上の要素をリストで取得する方法を考えます。 |
| + | |
| + | **リスト内包表記を使う [#x174eef9] |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultRist = [x for x in testList if x > 3] |
| + | |
| + | print resultRist |
| + | |
| + | 結果 |
| + | |
| + | [4, 5, 6] |
| + | |
| + | **高階関数filterを使う [#w0b1e268] |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultList = filter(lambda x : x > 3, testList) |
| + | |
| + | print resultList |
| + | |
| + | ここで第一引数は真偽型を戻り値とする関数です。ここではラムダ式で3より大きい時に真となる関数を定義しています。ラムダ式については「[[Python/ラムダ式]]」を参照のこと |
| + | |
| + | 結果 |
| + | |
| + | [4, 5, 6] |
| + | |
| + | ラムダ式の部分はもちろん関数でもかまいません。ただし簡単な物ならラムダ式の方がコンパクトに書けます。以下の物は上の例と全く同じ結果を返します。 |
| + | |
| + | def filterFunction(x): |
| + | return x > 3 |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultList = filter(filterFunction, testList) |
| + | |
| + | print resultList |
| + | |
| *要素を変換する [#q3175926] | | *要素を変換する [#q3175926] |
| + | |
| + | 例として全要素を2倍にする処理を考えます。 |
| + | |
| + | **リスト内包表記を使う [#ob56e668] |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultRist = [2 * x for x in testList] |
| + | |
| + | print resultRist |
| + | |
| + | 結果 |
| + | |
| + | [2, 4, 6, 8, 10, 12] |
| + | |
| + | |
| + | **高階関数mapを使う [#m314f3a3] |
| + | |
| + | 全要素を変換する場合はmapを使います。 |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultList = map(lambda x : x * 2, testList) |
| + | print resultList |
| + | |
| + | ここでmapの第一引数は引数を二倍にするラムダ式です。 |
| + | |
| + | 結果 |
| + | |
| + | [2, 4, 6, 8, 10, 12] |
| + | |
| + | *要素を検索して変換する [#u52822b9] |
| + | |
| + | 例として3より大きな要素を二倍することを考えます。 |
| + | |
| + | **リスト内包表記 [#kbc5a58c] |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultRist = [2 * x for x in testList if x > 3] |
| + | |
| + | print resultRist |
| + | |
| + | 結果 |
| + | |
| + | [8, 10, 12] |
| + | |
| + | **高階関数を組み合わせる [#rab2a1db] |
| + | |
| + | mapとfilterを組み合わせれば、同じことができます。 |
| + | |
| + | testList = [1,2,3,4,5,6] |
| + | |
| + | resultList = map(lambda x : x * 2, filter(lambda x : x > 3, testList)) |
| + | |
| + | print resultList |
| + | |
| + | 結果 |
| + | |
| + | [8, 10, 12] |
| + | |
| + | |
| + | *まとめ [#c4677d0f] |
| + | |
| + | 全体に簡単な処理ならリスト内包表記の方がコンパクトに書けて、しかも高速なので便利です。 |
| + | |
| + | 複雑な処理の場合は、別に関数を定義する高階関数の方がループ構造と処理が分かれるのでわかりやすいかもしれません。 |