Python初心者にとってわかりづらい記法として「内包表記」があります。 for文などを使っても同じ処理を書くことはできますが、内包表記を使用すれば、よりPythonらしいコードを書くことができます。
内包表記は、ひとつ以上のイテレータからPythonデータ構造をコンパクトに作れる形式だ。内包表記を使えば、ループや条件テストを寡黙な構文で結合できる。内包表記が使えるかどうかは、Python初心者レベルを卒業できているかどうかの目印になる。 引用:入門Python3 Bill Lubanovic 著
一見、わかりづらそうですが、慣れると読みやすく、内包表記があるからこそPythonを使用しているプログラマもいるほどです。
Python初心者から卒業するためにも内包表記を理解しましょう。
動作確認環境
- OS X Yosemite 10.10.5
- Python 3.5.1
内包表記を書いてみましょう
1.基本
たとえば、1から5までのリストをつくる場合、for文であれば下記のように記載します。
n_list = [] for n in range(1,6): n_list.append(n) n_list # => [1, 2, 3, 4, 5]
もちろん上記でも間違いというわけではありませんが、Pythonianからすればスマートなコードとは言えないでしょう。
上記を内包表記で書き直すと下記のようになります。
n_list = [n for n in range(1,6)] n_list # => [1, 2, 3, 4, 5]
非常にシンプルですね。 さらに内包表記だとfor文で記載するよりも実行速度が速いです。
なお、上のコードは内包表記の中のリスト内包表記と呼ばれるものです。 [] に定義し、リストを返します。
では、もう少し、内包表記の例を見てみましょう。
たとえば、べき乗のリストを作成するには下記のように記載します。
n_list = [n*n for n in range(1,6)] n_list # => [1, 4, 9, 16, 25]
ここまでは、それほど難しくないと思います。
2.条件式の追加 if
ここから少し難しくなるかもしれません。
ここからが内包表記の本領発揮ともいえるのですが、 リスト内包表記には条件式を追加することができます。
たとえば、偶数のリストを得るためには下記のよう記載します。
n_list = [n for n in range(1,6) if n % 2 == 1] n_list # => [1, 3, 5]
仮にfor文で書くとしたら、下記のようになりますので、表示にシンプルにプログラムが書けます。
n_list = [] for n in range(1,6): if n % 2 == 1: n_list.append(n) n_list # => [1, 3, 5]
3.条件式の追加 if else
次に条件式が一つだけの場合、すなわちif文のみの場合ではなく、 if elseの場合の内包表記についても説明したいと思います。
ifだけでなく、else節がある場合、少しややこしいのですが、書き方が少し変わります。 具体的には、内包表記の中で三項演算子を利用するので、if文の位置が変化します。
なお、三項演算子について少し解説すると、三項演算子は
(条件がTrueのときの値) if (条件) else (条件がFalseのときの値)
という記述がなります。
たとえば、nが偶数の場合は変数strに「even」、奇数の場合は変数strに「odd」と代入する場合、通常の書き方であれば下記のようになります。
if n % 2 == 0 str="even" else str="odd"
それを、三項演算子で記述すると下記のようになります。
str = "even" if n % 2 == 0 else "odd"
参考演算子についてはお分かりいただけたでしょうか。
では、話を戻します。
上記を踏まえた上で、内包表記でif else文を使用するにはどうするのでしょうか。
たとえば、あまり実益のあるプログラムとは言えないですが、1から10までのリスト([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])があり、奇数の場合はodd、偶数の場合はevenとなるリストを作成するには、下記のように記載します。
n_list = ["even" if i%2==0 else "odd" for i in range(1,11)] n_list # => ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd','even']
if〜elseを内包表記に追加することができました。
4.ネスト(多重配列)
さらに内包表記はネストすることができます。
たとえば、九九の表を作成するとしたら、下記のように記載します。
n_list = [[x*y for x in range(1,10)] for y in range(1, 10)] n_list #=>[[1, 2, 3, 4, 5, 6, 7, 8, 9], [2, 4, 6, 8, 10, 12, 14, 16, 18], [3, 6, 9, 12, 15, 18, 21, 24, 27], [4, 8, 12, 16, 20, 24, 28, 32, 36], [5, 10, 15, 20, 25, 30, 35, 40, 45], [6, 12, 18, 24, 30, 36, 42, 48, 54], [7, 14, 21, 28, 35, 42, 49, 56, 63], [8, 16, 24, 32, 40, 48, 56, 64, 72], [9, 18, 27, 36, 45, 54, 63, 72, 81]]
通常のfor文で書くとするなら下記のようになります。 内包表記だと、シンプルに記載できますね。
outer_list=[] for x in range(1,10): inner_list=[] for y in range(1,10): inner_list.append(x*y) outer_list.append(inner_list) outer_list
今回は以上です。
参考