python 特定の値がリストに格納されているか確認する方法

特定の値がリストに格納されているか確認する方法を紹介します。
「inを利用する方法」と「setとinを利用する方法」があり、条件により実行時間が短い方法が異なります。実行時間については以降で説明しております。

inを利用する方法

l = [1, 2, 3, 4, 5]
print(5 in l)
print(6 in l)

"""出力
True
False
"""
  • リストlの中に、5か6があるか判定しています。

setとinを利用する方法

list型にinを使用するよりも、set型に変換した後にinを使用した方が、実行時間が短くなる場合があります。正確にどちらの方が実行時間が短くなるか知るには、それぞれの処理について比較する必要がありますが、目安は下記です。

  • リストや集合の要素数が10以上で、inを使用する回数が3回以上の場合(setによる変換は1回のみ行う)は、「setとinを利用する方法」の方が「inを利用する方法」よりも実行時間が短くなるので、「setとinを利用する方法」をとる。

「setとinを利用する方法」は、集合に変換する分の時間は掛かりますが、集合に対してinを使用する時の実行時間が非常に短いため、特定の条件(上記の目安参照)では「setとinを利用する方法」の方が効率が良くなります。下記に、「任意のリストまたは集合(リストをsetで変換したもの)に対して、任意の回数inを使用した時の実行時間」に影響を与える要素を示します。

  • inの対象(リストや集合)の要素数
  • 変換後の集合にinを使用する回数

特に、変換後の集合にinを使用する回数が実行時間に影響を与えます。測定方法は、「list関数とset関数の実行時間比較」を確認してください。

l = [1, 2, 3, 4, 5]
s = set(l)
print(5 in s)
print(6 in s)

"""出力
True
False
"""

list関数とset関数の実行時間比較

下記条件で、実行時間を測定しました。
    反復回数は100,000回、リストと集合の要素数は1~100,000個
下記コードの出力は処理を1回ではなく、100,000回行った時間ですので注意してください。

結論は下記です。

  • 要素数が極端に少ない時(1 等)は、setを使用してリストに変換した方が実行時間が短い
  • 要素数が10以上の時は、inを使用する回数が3回以上の場合に「setとinを利用する方法」の方が「inを利用する方法」よりも実行時間が短くなる

下記結果を例に、inを使用する回数が3回以上の場合は、「setとinを利用する方法」の方が実行時間が短くなることを示します。
  size = 100000
  list : 164.31664489998366 ①リストにinをした時の実行時間
  setのみ : 387.36317610001424 ②set(リスト)をした時の実行時間
  集合に対してinのみ : 0.006789499981096014 ③集合にinをした時の実行時間
  setとin / list : 2.357460291596021 ④

  • リストにinを3回利用する方法の実行時間:
    • 3 * ① = 492.95
  • リストを集合に変換し、inを3回利用する方法(setとinを利用する方法)の実行時間:
    • ② + 3 * ③ = 387.38
import timeit

rep = 10**5
size = 1
while size <= 10**5:
    l = list(range(size))
    print("size = " + str(size))

    lTime =  timeit.timeit("size-1 in l", globals=globals(), number=rep)
    onlySetTime =  timeit.timeit("set(l)", globals=globals(), number=rep)
    onlyInTime =  timeit.timeit("size-1 in s", setup="s=set(l)", globals=globals(), number=rep)
    print("list                 : ", lTime)
    print("setのみ              : ", onlySetTime)
    print("集合に対してinのみ   : ", onlyInTime)
    print("setとin / list       : ", (onlySetTime+onlyInTime)/lTime)
    size *= 10
"""出力
size = 1
list                 :  0.006987100001424551
setのみ              :  0.021156700007850304
集合に対してinのみ    :  0.00844509998569265
setとin / list       :  4.236636084714352

size = 10
list                 :  0.027269500016700476
setのみ              :  0.038946099986787885
集合に対してinのみ    :  0.004612499993527308
setとin / list       :  1.5973376832592785

size = 100
list                 :  0.1684909999894444
setのみ              :  0.18375540000852197
集合に対してinのみ    :  0.004556400002911687
setとin / list       :  1.1176371439615824

size = 1000
list                 :  1.2606704999925569
setのみ              :  1.4146807999932207
集合に対してinのみ    :  0.007337500021094456
setとin / list       :  1.1279857028642384

size = 10000
list                 :  12.96388900000602
setのみ              :  13.209038100001635
集合に対してinのみ    :  0.007618900010129437
setとin / list       :  1.0194978528438208

size = 100000
list                 :  164.31664489998366
setのみ              :  387.36317610001424
集合に対してinのみ    :  0.006789499981096014
setとin / list       :  2.357460291596021
"""

参考

(5) Why is a set faster than a list in Python? – Quora
list型よりもset型に対してinを利用した時の方が、実行時間が速い理由

コメント

タイトルとURLをコピーしました