Python3における内包表記について

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

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

今回は以上です。

参考

  • このエントリーをはてなブックマークに追加
  • Pocket
  • LINEで送る

SNSでもご購読できます。

コメントを残す

*

CAPTCHA