あなたの「仕事の説明」を理解しているかどうかわかりませんが、あなたはこれを望んでいると思います:
def find_matches(tuple_of_dicts, key_to_find):
return [d for d in tuple_of_dicts if key_to_find in d]
そう:
>>> tuple_of_dicts = ({18: None}, {10: None}, {16: None, 18: None, 5: None, 6: None, 7: None, 10: None}, {16: None}, {7: None}, {10: None}, {18: None}, {16: None, 10: None, 18: None, 7: None}, {10: None, 18: None, 7: None}, {10: None}, {7: None}, {7: None}, {10: None, 7: None}, {7: None})
>>> find_matches(tuple_of_dicts, 18)
[{18: None},
{5: None, 6: None, 7: None, 10: None, 16: None, 18: None},
{18: None},
{7: None, 10: None, 16: None, 18: None},
{7: None, 10: None, 18: None}]
それは線形時間で機能します。タプルに N 個のディクテーションがあり、それぞれ平均して M メンバーである場合、タプルをたどって、反復ごとに一定時間のディクテーション ルックアップを実行し、合計 O(N) になります。
しかし、このような検索を多数行う場合は、線形時間よりもさらに優れた結果を得ることができます。
秘訣は (ご想像のとおり) インデックス ディクショナリを作成し、各キーをそれが含まれるディクショナリのインデックス、または単にディクショナリ自体にマッピングすることです。例えば:
>>> dict_of_dicts = {}
>>> for d in tuple_of_dicts:
... for key in d:
... dict_of_dicts.setdefault(key, []).append(d)
>>> def find_matches(dict_of_dicts, key_to_find):
... return dict_of_dicts[key_to_find]
これには、セットアップ作業を行うのに O(N*M) の時間が必要であり、O(N*M) スペースの辞書を作成します*。ただし、検索ごとに単純な O(1) 辞書検索になります。したがって、M 回以上の検索を行っていて、余分なスペースを確保できる限り、それは大きな利益になります。
* 正確に言うと、L 個の個別のキー、合計 M 個のキーがある場合、dict で N*M 回のルックアップを行い、dict に N*M/L 回追加し、M/L の長さのリストに N*M 回追加します。 . リストの追加は一定時間償却されるため、O(N*M + N*M/L + N*M) = O(N*M) セットアップ時間です。一方、dict は O(N*L) スペースであり、各メンバーは長さ O(M/L) のリストであるため、リストに使用される合計スペースは O(N*L * M/L) = O( N*M) であり、dict とそのリストの合計スペースは O(N*L + N*M) = O(N*M) です。最後に、検索は値をハッシュし、それを dict で検索し、M/L 長リストへの参照を返します。これらはすべて一定時間の操作であるため、各検索は O(1) です。