ジェネレーター式と内包表記を使ってみよう特集:Visual Studioで始めるPythonプログラミング(2/2 ページ)

» 2016年10月14日 05時00分 公開
[かわさきしんじInsider.NET編集部]
前のページへ 1|2       

少し高度な内包表記の例

 前ページで見た内包表記は非常にシンプルなものだったが、二重のforループに相当する処理を内包表記で表現したり、「式」を適用する前に要素のフィルタリングを行ったりすることもできる。以下では、少し高度な内包表記の使い方を見てみよう。

for節のネスト

 まずは以下のforループを見てみよう。

>>> l = []
>>> for x in range(3):
...   for y in range(4):
...     l.append((x, y))
...
>>> l
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), …… 省略 ……, (2, 2), (2, 3)]


for文の二重ループ

 このコードではfor文を二重にループさせて、(0, 0)〜(2, 3)のタプルをリストに追加している。これと同等な処理を内包表記で記述すると次のようになる。

>>> l = [(x, y) for x in range(3) for y in range(4)]
>>> l
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), …… 省略 ……, (2, 2), (2, 3)]


内包表記による二重ループの表現

 このように「for節」(for ターゲットリスト in 反復可能オブジェクト)をネストさせることで、二重ループをするよりも簡潔な形でコードを記述できる。for文を使った場合とループと同じ順序でfor節をネストさせればよいので、forループのネストからfor節のネストへの頭の切り替えはそれほど難しくはないだろう。このことが手や体や頭に染みついてきたら、次の内包表記の意味も分かるようになる。

>>> [num for item in [[1], [2, 3], [4, 5, 6]] for num in item]
[1, 2, 3, 4, 5, 6]


リストを要素とするリストのフラット化

 ネストしたfor節はネストしたfor文と同じ順序で書かれるので、これはおおよそ次のようなforループと同等だと考えればよい。

for item in [[1], [2, 3], [4, 5, 6]]:
  for num in item:
    # numをリストの要素に追加


内包表記のfor文への展開

 一見すると難解な表現でも、最初のうちは自分が理解できている構文要素へ展開してみると「ああ、そういうことか」となるので、つまずいたときには基本に戻ってみるようにしよう。

if節による要素のフィルタリング

 for節に続けて「if節」を記述すると、元の反復可能オブジェクトから要素をフィルタリングできる。以下に例を示す。

>>> l = ["Windows Server Insider", "Insider.NET", "Server & Storage", "HTML5 + UX"]
>>> l2 = [item for item in l if "Insider" in item# "Insider"が含まれる要素からなるリストを作成
>>> l2
['Windows Server Insider', 'Insider.NET']
>>> s = {x * x for x in range(10) if x % 2 == 0# 偶数のみを取り出し、その二乗からなる集合を作成
>>> s
{0, 16, 64, 4, 36}
>>> s = {x * x for x in range(10) if x % 2# 奇数のみを取り出し、その二乗からなる集合を作成
>>> s
{81, 1, 49, 9, 25}


if節によるフィルタリング

 for節がネストしている場合、if節はそれぞれに付加できる。以下はrange(5)の範囲でxには奇数のみ、yには偶数のみを取り出して、それらを組み合わせたタプルを要素とするリストを作成している。

>>> [(x, y) for x in range(5) if x % 2 for y in range(5) if not y % 2]
[(1, 0), (1, 2), (1, 4), (3, 0), (3, 2), (3, 4)]


2つのfor節のそれぞれにif節を追加

 なお、Pythonでは三項演算子(条件演算子)の代わりに条件式が使える。以下に構文を示す。

式1 if 条件 else 式2


Pythonの条件式

 この式ではまず「条件」が評価される。その値が真であれば「式1」の値が、偽であれば「式2」の値がその式の評価結果となる。そのため、else以降を省略することはできない。

 使用例を以下に示す。以下は乱数が偶数か奇数かでその値が変化する条件式だ。

>>> import random
>>> 100 if random.randint(0,10) % 2 else 200
100
>>> 100 if random.randint(0,10) % 2 else 200
200


条件式の使用例

 この条件式を「式」部分に記述することも可能だ。for節に続けるif節とは異なるので注意が必要だ。強調表示した部分が内包表記の「式」に当たる。

>>> l = ["Windows Server Insider", "Insider.NET", "Server & Storage", "HTML5 + UX"]
>>> [item if "Insider" in item else "outsider" for item in l]
['Windows Server Insider', 'Insider.NET', 'outsider', 'outsider']


条件式の使用例

zip関数との組み合わせ

 最後にzip関数を使った辞書の作成を見てみる。zip関数は複数の反復可能オブジェクトを受け取り、それらの要素を一組にしたタプル(のイテレータ)を返送する。これを利用すると、例えば、以下のような辞書を作成できる。

>>> l = ["Windows Server Insider", "Insider.NET", "Server & Storage", "HTML5 + UX"]
>>> {"forum {0}".format(n) : forum for n, forum in zip(range(1,5), l)}
{'forum 2': 'Insider.NET', 'forum 4': 'HTML5 + UX', 'forum 3': 'Server & Storage', 'forum 1': 'Windows Server Insider'}


zip関数と組み合わせて、辞書を作成


 今回は前回積み残したジェネレーター式と、それとよく似た構文を持つリスト/集合/辞書の内包表記について見てきた。次回はモジュールとクラスなどを取り上げる予定だ。

「特集:Visual Studioで始めるPythonプログラミング」のインデックス

特集:Visual Studioで始めるPythonプログラミング

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。