note.nkmk.me

Pythonのin演算子でリストなどに特定の要素が含まれるか判定

Date: 2019-06-12 / tags: Python, リスト

Pythonの演算子inおよびnot inを使うと、リストやタプルなどに特定の要素が含まれるかどうかを確認・判定できる。

ここでは以下の内容について説明する。

  • in演算子の使い方
    • 基本的な使い方
    • if文での条件分岐
    • 辞書dictに対するin
    • 文字列strに対するin
  • not in(否定)で存在しないことを確認
  • 複数の要素に対するin
    • and, orを使う
    • 集合を使う
  • for文やリスト内包表記におけるin

for文やリスト内包表記の構文においてもinという語句が使われる。本記事の最後でも触れるが、詳細は以下の記事を参照。

スポンサーリンク

in演算子の使い方

基本的な使い方

以下のようにx in yの形で記述する。xyに含まれているとTrue、含まれていないとFalseを返す。

print(1 in [0, 1, 2])
# True

print(100 in [0, 1, 2])
# False
source: in_basic.py

リストのほか、タプルや集合setrangeなどのイテラブルオブジェクトに対する演算が可能。

print(1 in (0, 1, 2))
# True

print(1 in {0, 1, 2})
# True

print(1 in range(3))
# True
source: in_basic.py

辞書dict、文字列strについては後述。

if文での条件分岐

inによる演算はbool値(True, False)を返すので、そのままif文の条件式として使える。

l = [0, 1, 2]
i = 0

if i in l:
    print('{} is a member of {}.'.format(i, l))
else:
    print('{} is not a member of {}.'.format(i, l))
# 0 is a member of [0, 1, 2].
source: in_basic.py
l = [0, 1, 2]
i = 100

if i in l:
    print('{} is a member of {}.'.format(i, l))
else:
    print('{} is not a member of {}.'.format(i, l))
# 100 is not a member of [0, 1, 2].
source: in_basic.py

なお、リストやタプル、文字列などは空だとFalse、空でなければTrueと判定される。空かどうかで条件分岐したい場合はオブジェクトをそのまま条件式として使えばよい。

l = [0, 1, 2]

if l:
    print('not empty')
else:
    print('empty')
# not empty
source: in_basic.py
l = []

if l:
    print('not empty')
else:
    print('empty')
# empty
source: in_basic.py

各型の真偽の判定については以下の記事も参照。

辞書dictに対するin

辞書dictをそのままin演算で使うと、キーに対する判定となる。

d = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}

print('key1' in d)
# True

print('value1' in d)
# False
source: in_basic.py

値、あるいは、キーと値の組み合わせに対して処理したい場合はvalues(), items()を使う。

print('value1' in d.values())
# True

print(('key1', 'value1') in d.items())
# True

print(('key1', 'value2') in d.items())
# False
source: in_basic.py

詳細は以下の記事を参照。

文字列strに対するin

文字列strに対しては部分文字列の判定が可能。

print('a' in 'abc')
# True

print('x' in 'abc')
# False

print('ab' in 'abc')
# True

print('ac' in 'abc')
# False
source: in_basic.py

文字列の検索についての詳細は以下の記事を参照。正規表現を使ったより柔軟な判定についても触れている。

not in(否定)で存在しないことを確認

in演算子の否定はnot inを使う。

print(10 in [1, 2, 3])
# False

print(10 not in [1, 2, 3])
# True
source: in_basic.py

in演算全体にnotを付けても同じ結果。

print(not 10 in [1, 2, 3])
# True
source: in_basic.py

ただし、in演算全体にnotを付けると、以下のようにnotがどの範囲に掛かっているかについて2通りの解釈ができてしまうため、より明確なnot inを使うことが推奨されている。

print(not (10 in [1, 2, 3]))
# True

print((not 10) in [1, 2, 3])
# False
source: in_basic.py

inのほうがnotより優先順位が高い(先に処理される)ため、括弧がない場合は前者として処理される。

ちなみに後者の場合は以下のように認識される。

print(not 10)
# False

print(False in [1, 2, 3])
# False
source: in_basic.py

複数の要素に対するin

複数の要素が含まれているかを判定したい場合、以下のように複数の要素をリストで書いてもうまくいかない。リスト自体が含まれているかの判定になってしまう。

print([0, 1] in [0, 1, 2])
# False

print([0, 1] in [[0, 1], [1, 0]])
# True
source: in_basic.py

and, orを使うか、集合setを使う。

and, orを使う

論理演算子and(かつ)、or(または)を使って、複数のin演算を組み合わせる。どちらも含まれている、あるいは、どちらかが含まれている、という判定になる。

l = [0, 1, 2]
v1 = 0
v2 = 100

print(v1 in l and v2 in l)
# False

print(v1 in l or v2 in l)
# True

print((v1 in l) or (v2 in l))
# True
source: in_basic.py

in, not inのほうがand, orより優先順位が高い(先に処理される)ので括弧は必要ないが、分かりにくい場合は最後の例のように括弧で囲んでもOK。

集合を使う

判定したい要素の数が多い場合は、and, orよりも集合setを使うほうが簡単。

set()で集合に変換したあとで集合演算を行う。集合演算についての詳細は以下の記事を参照。

例えば、リストAリストBの要素がすべて含まれているかは、リストBリストAの部分集合か(またはリストAリストBの上位集合か)を判定すればよい。

l1 = [0, 1, 2, 3, 4]
l2 = [0, 1, 2]
l3 = [0, 1, 5]
l4 = [5, 6, 7]

print(set(l2) <= set(l1))
# True

print(set(l3) <= set(l1))
# False
source: in_basic.py

リストAリストBの要素がひとつも含まれていないことを判定したい場合は、リストAリストBが互いに素であるかを確認すればよい。

print(set(l1).isdisjoint(set(l4)))
# True
source: in_basic.py

リストAリストBが互いに素でなければ、リストAリストBの要素が少なくともひとつは含まれていると判定できる。

print(not set(l1).isdisjoint(set(l3)))
# True
source: in_basic.py

集合を利用することで共通の要素を抽出したりすることも可能。以下の記事を参照。

for文やリスト内包表記におけるin

for文やリスト内包表記の構文においてもinという語句が使われる。このinin演算子ではなく、TrueまたはFalseを返しているわけではない。

l = [0, 1, 2]

for i in l:
    print(i)
# 0
# 1
# 2
source: in_basic.py
print([i * 10 for i in l])
# [0, 10, 20]
source: in_basic.py

for文やリスト内包表記についての詳細は以下の記事を参照。

リスト内包表記では条件式としてin演算子を使う場合があり、ややこしいので注意。

l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']

l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']

はじめのinがリスト内包表記のinで、うしろのinin演算子。

スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事