Python リストに値が存在するかどうかをすばやく確認する方法
胡金庫
2023年1月30日
Python リストに値が存在するかどうかを確認し、パフォーマンスを比較するさまざまな方法を紹介します。
メソッドには、
- メンバーシップチェックメソッド-
in
メソッドで値が存在するかどうかを確認します - リストを
set
に変換し、メンバーシップチェックメソッドin
を使用します
Python リストの値の存在を確認する in
メソッド
in
は、Python リスト、セット、辞書、またはその他の反復可能な Python オブジェクトのメンバーシップチェックを行う適切な方法です。
>>> testList = [1, 2, 3, 4]
>>> 2 in testList
True
>>> 6 in testList
False
リストを設定に変換してから、Python でメンバーシップチェックを実行する
リストのメンバーシップチェックは、リストのサイズが大きくなる場合、特にリストに重複する要素が存在する場合、非効率になる可能性があります。
Python セットは一意の値のみを含むため、このシナリオではメンバーシップチェックを行うのに適したデータ型です。
リストとセットメンバーシップチェックのパフォーマンス比較
4つの状況でパフォーマンスの違いを比較します。
- 元のリストには一意の値があり、チェックされた値はリストに存在します
- 元のリストには一意の値があり、チェックされた値はリストに存在しません
- 元のリストに重複した値があり、チェックされた値がリストに存在する
- 元のリストには重複した値のみがあり、チェックされた値はリストに存在しません
元のリストには一意の値のみがあり、チェックされた値はリストに存在する
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = a[: n // 2].tolist()
randomvalue = randomlist[len(randomlist) // 2]
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return y in x
def inSetMethod(L):
x, y = L
x = set(x)
return y in x
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=["in list", "in set"],
n_range=[2 ** k for k in range(1, 20)],
xlabel="Data Length",
title="unique values in list and to-be-checked value exists in the list",
logx=True,
logy=True,
)
元のリストには一意の値のみがあり、チェックされた値はリストに存在しません
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = a[: n // 2].tolist()
randomvalue = n + 1
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return y in x
def inSetMethod(L):
x, y = L
x = set(x)
return y in x
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=["in list", "in set"],
n_range=[2 ** k for k in range(1, 20)],
xlabel="Data Length",
title="unique values in list and to-be-checked value does not exist in the list",
logx=True,
logy=True,
)
元のリストには重複した値があり、チェックされた値はリストに存在する
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = np.random.choice(n, n // 2).tolist()
randomvalue = randomlist[len(randomlist) // 2]
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return y in x
def inSetMethod(L):
x, y = L
x = set(x)
return y in x
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=["in list", "in set"],
n_range=[2 ** k for k in range(2, 20)],
xlabel="Data Length",
title="duplicate values in list and to-be-checked value exists in the list",
logx=True,
logy=True,
)
元のリストには重複した値のみがあり、チェックされた値はリストに存在しません
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
randomlist = np.random.choice(n, n // 2).tolist()
randomvalue = n + 1
return [randomlist, randomvalue]
def inListMethod(L):
x, y = L
return y in x
def inSetMethod(L):
x, y = L
x = set(x)
return y in x
perfplot.show(
setup=setupTest,
kernels=[inListMethod, inSetMethod],
labels=["in list", "in set"],
n_range=[2 ** k for k in range(2, 20)],
xlabel="Data Length",
title="duplicate values in list and to-be-checked value does not exist in the list",
logx=True,
logy=True,
)
パフォーマンス比較の結論
Python の set
のメンバーシップチェックは Python リストのメンバーシップチェックよりも高速ですが、list または set
からの変換には時間がかかります。したがって、指定されたデータが Python リストである場合、最初にリストを set
に変換してから set
でメンバーシップチェックを行うと、パフォーマンス上のメリットはありません。
from itertools import chain
import perfplot
import numpy as np
def setupTest(n):
a = np.arange(n)
np.random.shuffle(a)
unique_randomlist = a[: n // 2].tolist()
duplicate_randomlist = np.random.choice(n, n // 2).tolist()
existing_randomvalue = unique_randomlist[len(unique_randomlist) // 2]
nonexisting_randomvalue = n + 1
return [
unique_randomlist,
duplicate_randomlist,
existing_randomvalue,
nonexisting_randomvalue,
]
def inListMethod_UniqueValue_ValueExisting(L):
u, d, ex, ne = L
return ex in u
def inListMethod_DuplicateValue_ValueExisting(L):
u, d, ex, ne = L
return ex in d
def inListMethod_UniqueValue_ValueNotExisting(L):
u, d, ex, ne = L
return ne in u
def inListMethod_DuplicateValue_ValueNotExisting(L):
u, d, ex, ne = L
return ne in d
def inSetMethod_UniqueValue_ValueExisting(L):
u, d, ex, ne = L
u = set(u)
return ex in u
def inSetMethod_DuplicateValue_ValueExisting(L):
u, d, ex, ne = L
d = set(d)
return ex in d
def inSetMethod_UniqueValue_ValueNotExisting(L):
u, d, ex, ne = L
u = set(u)
return ne in u
def inSetMethod_DuplicateValue_ValueNotExisting(L):
u, d, ex, ne = L
d = set(d)
return ne in d
perfplot.show(
setup=setupTest,
equality_check=None,
kernels=[
inListMethod_UniqueValue_ValueExisting,
inListMethod_DuplicateValue_ValueExisting,
inListMethod_UniqueValue_ValueNotExisting,
inListMethod_DuplicateValue_ValueNotExisting,
inSetMethod_UniqueValue_ValueExisting,
inSetMethod_DuplicateValue_ValueExisting,
inSetMethod_UniqueValue_ValueNotExisting,
inSetMethod_DuplicateValue_ValueNotExisting,
],
labels=[
"inListMethod_UniqueValue_ValueExisting",
"inListMethod_DuplicateValue_ValueExisting",
"inListMethod_UniqueValue_ValueNotExisting",
"inListMethod_DuplicateValue_ValueNotExisting",
"inSetMethod_UniqueValue_ValueExisting",
"inSetMethod_DuplicateValue_ValueExisting",
"inSetMethod_UniqueValue_ValueNotExisting",
"inSetMethod_DuplicateValue_ValueNotExisting",
],
n_range=[2 ** k for k in range(2, 20)],
xlabel="Data Length",
logx=True,
logy=True,
)
著者: 胡金庫