Python リストに値が存在するかどうかをすばやく確認する方法

胡金庫 2023年1月30日
  1. Python リストの値の存在を確認する in メソッド
  2. リストを設定に変換してから、Python でメンバーシップチェックを実行する
  3. リストとセットメンバーシップチェックのパフォーマンス比較
Python リストに値が存在するかどうかをすばやく確認する方法

Python リストに値が存在するかどうかを確認し、パフォーマンスを比較するさまざまな方法を紹介します。

メソッドには、

  1. メンバーシップチェックメソッド-in メソッドで値が存在するかどうかを確認します
  2. リストを set に変換し、メンバーシップチェックメソッド in を使用します

Python リストの値の存在を確認する in メソッド

in は、Python リスト、セット、辞書、またはその他の反復可能な Python オブジェクトのメンバーシップチェックを行う適切な方法です。

>>> testList = [1, 2, 3, 4]
>>> 2 in testList
True
>>> 6 in testList
False

リストを設定に変換してから、Python でメンバーシップチェックを実行する

リストのメンバーシップチェックは、リストのサイズが大きくなる場合、特にリストに重複する要素が存在する場合、非効率になる可能性があります。

Python セットは一意の値のみを含むため、このシナリオではメンバーシップチェックを行うのに適したデータ型です。

リストとセットメンバーシップチェックのパフォーマンス比較

4つの状況でパフォーマンスの違いを比較します。

  1. 元のリストには一意の値があり、チェックされた値はリストに存在します
  2. 元のリストには一意の値があり、チェックされた値はリストに存在しません
  3. 元のリストに重複した値があり、チェックされた値がリストに存在する
  4. 元のリストには重複した値のみがあり、チェックされた値はリストに存在しません

元のリストには一意の値のみがあり、チェックされた値はリストに存在する

Python は値がリストに存在するかどうか-リスト内の一意の値とチェック対象の値は list.png に存在する

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,
)

元のリストには一意の値のみがあり、チェックされた値はリストに存在しません

Python はリストに値が存在するかどうか-リスト内の一意の値とチェックされる値はリストに存在しません

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,
)

元のリストには重複した値があり、チェックされた値はリストに存在する

Python はリストに値が存在するかどうか-リスト内の値が重複しており、チェック対象の値がリスト内に存在する

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,
)

元のリストには重複した値のみがあり、チェックされた値はリストに存在しません

Python はリストに値が存在するかどうか-リスト内の値が重複しており、チェック対象の値がリストに存在しない

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 でメンバーシップチェックを行うと、パフォーマンス上のメリットはありません。

Python が値がリストに存在するかどうか-概要

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,
)
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - Python List