連載
» 2021年07月06日 05時00分 公開

[解決!Python]リストの内包表記と「if」を組み合わせるには解決!Python

リストの内包表記の中でif句と条件式(if式)を利用して、より柔軟な形で新たなリストの要素を計算する方法を見る。if句と代入式を組み合わせる方法も紹介。

[かわさきしんじ,Deep Insider編集部]

この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。

「解決!Python」のインデックス

連載目次

# if句を使用して、要素を計算する前にフィルタリングをする
r = range(11)
odd_list = [x for x in r if x % 2]
print(odd_list)  # [1, 3, 5, 7, 9]

even_list = [x for x in r if x % 2 == 0]
# even_list = [x for x in r if x not in odd_list]
print(even_list)  # [0, 2, 4, 6, 8, 10]

# 内包表記の要素を決定する式で条件式(三項演算子)を使う
odd_even_list = [(x, 'odd') if x % 2 else (x, 'even') for x in r]
print(odd_even_list)
# 出力結果
#[(0, 'even'), (1, 'odd'), (2, 'even'), (3, 'odd'), (4, 'even'), (5, 'odd'),
# (6, 'even'), (7, 'odd'), (8, 'even'), (9, 'odd'), (10, 'even')]

# if句と代入式の組み合わせ
numlist = [0.06, 0.85, 0.96, 0.79, -0.73, 0.30, -0.81, -0.57, 0.56, 0.32]

def f(x):
    return x + 0.5  # ここでは「何らかの処理」=0.5を加える

numlist2 = [(x, y) for x in numlist if (y := f(x)) > 1]
print(numlist2)  # [(0.85, 1.35), (0.96, 1.46), (0.79, 1.29), (0.56, 1.06)]


if句を使用して、要素を計算する前にフィルタリングをする

 「[解決!Python]内包表記でリストを作成するには」では、内包表記を使ってリストを作成する基本的なパターンや、for句(for節ともいう)をネストさせるパターンなどを紹介した。しかし、内包表記では「if句」(if節ともいう)を使ったり、条件式(if式、三項演算子)を組み合わせたりすることで、より柔軟な形で要素の値を計算できるようになる。

 まずはリストの内包表記のif句から見ていこう。以下はその基本構文だ。

some_var = [expression for item in iterable_obj if condition]


 これは要素の値を計算する前に、「if condition」に記述した条件(condition)が真になるかどうかをテストして、その結果が真の場合にのみ、「expression」が評価されて、その結果が新たなリストの要素となることを意味する。通常、「condition」は「iterable_obj」から「item」に反復的に代入される値を使って表される。このとき、elseに対応する句は存在しない点には注意すること。

 これと同じことをするコードは次のようになる。

some_var = []
for item in iterable_obj:
    if condition:
        some_var.append(expression)


 if句の使用例を以下に示す。

r = range(11)
odd_list = [x for x in r if x % 2]
print(odd_list)  # [1, 3, 5, 7, 9]

even_list = [x for x in r if x % 2 == 0]
# even_list = [x for x in r if x not in odd_list]
print(even_list)  # [0, 2, 4, 6, 8, 10]


 最初の例では、反復可能オブジェクトrから取り出した値は変数xに代入され、「expression」として記述した式「x」が評価される前に、if句で「x % 2」が真であるかどうかがテストされる。この式は「xを2で整数除算した余りを求める」ものなので、その値は0か1となり、結果が1のときは真と見なされるので、余りが1=xが奇数のときには「expression」に書いた式「x」が評価されることになる。つまり、「0〜10の値のうち、奇数を要素とするリスト」が作成される。

 2つ目の例は、その逆で「0〜10の値のうち、偶数を要素とするリスト」を得るものだ。コメントに記したように、条件は数値を計算するものである必要はなく、Pythonで真偽値として扱えるものが得られるのであれば、どのようなものでもよい。

 既に述べたが、注意が必要なのは、if文やif式では条件が成立しなかったときの振る舞いを記述できるが、if句ではこれは不可能であることだ。if句は反復可能オブジェクトから得た値を新たな要素の値の計算に使うかどうかを判断する(フィルタリングする)のであって、反復可能オブジェクトから得た値に応じて新たな要素の値を計算する方法を切り替える(処理を分岐する)ためのものではないと考えた方がよいだろう。後者であれば、この後で説明する条件式を使用する。

 内包表記のfor句と同様に、if句も複数記述できる。以下に例を示す。

values = [(x, y) for x in range(5) if x % 2 for y in range(5) if not y % 2]
print(values)  # [(1, 0), (1, 2), (1, 4), (3, 0), (3, 2), (3, 4)]


 最初のfor句に続くif句の条件は「xの値が奇数なら」を、次のfor句に続くif句の条件は「yの値が偶数なら」を意味するので、この結果は「1と3」と「0と2と4」を組み合わせたタプルを要素とするリストになる。これをfor文とif文を組み合わせたコードに書き下すと次のようになる。

values = []
for x in range(5):
    if x % 2:
        for y in range(5):
            if not y % 2:
                values.append((x, y))

print(values)


 for句とif句は必要なだけ続けられるが、コードが難解になることがないように注意しよう。

内包表記の要素を決定する式で条件式(if式、三項演算子)を使う

 条件式(if式、三項演算子)は、if文とは異なり、式を記述可能な部分で条件分岐を行うのに使える。これを使うと、反復可能オブジェクトから得た値に応じて、新たな値の計算方法を切り替えられる。以下に例を示す。

r = range(11)

odd_even_list = [(x, 'odd') if x % 2 else (x, 'even') for x in r]
print(odd_even_list)
# 出力結果
#[(0, 'even'), (1, 'odd'), (2, 'even'), (3, 'odd'), (4, 'even'), (5, 'odd'),
# (6, 'even'), (7, 'odd'), (8, 'even'), (9, 'odd'), (10, 'even')]


 このコードでは、「expression」の部分で条件式を使用して、xが奇数か偶数かでその計算方法(ここでは元の値と'even'か'odd'の文字列を組み合わせたタプルを生成する)を切り替えている。

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

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

メールマガジン登録

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