0

それぞれ 2 つの文字列と 1 つの整数を含む数十のタプルがあります。例: (str, str, int). これらのタプルはすべてリストにあります (以下の例)。各タプルは一意であり、各タプルの文字列と整数も一意です。

元。:

[('a','aA', 53),
 ('b','bb', 21),
 ('c','cc', 234),
 ('d','de', 76),
..]

私が望むのは、このデータ構造を辞書のように使用し、渡す3 つの値のいずれかのタプル全体を取得することです。

元。:

値の場合'a'-> 以下のタプル全体を取得:('a', 'aA', 53)

値の場合'cc'-> 以下のタプル全体を取得:('c', 'cc', 234)

値の場合'76'- > 次のタプル全体を取得します。('d', 'de', 76)

これまで のところ、タプルのリストを反復処理する単純な関数を作成し、各タプルとその 3 つの値すべてを調べて一致を見つけ、一致する場合はタプルを返し、そうでない場合は False を返します。

これは遅いように聞こえ、このタスクを行うには非常に間違った方法のように思えます。

  1. これを達成するための正しい方法は何ですか?
  2. 3 つの辞書を作成して相互にリンクする必要がありますか?
4

3 に答える 3

1

コンテンツごとに要素を検索できるようにするには、辞書を使用して個別のインデックスを作成する必要があります。

from collections import defaultdict

index_on_1 = defaultdict(list)
index_on_2 = defaultdict(list)
index_on_3 = defaultdict(list)

for i, (val1, val2, val3) in enumerate(yourstructure):
    index_on_1[val1].append(i)
    index_on_2[val2].append(i)
    index_on_3[val3].append(i)

これで、文字列のインデックスを検索できます。

from itertools import chain

def lookup(entry):
    if isinstance(entry, str):
        entries = chain(index_on_1.get(entry, []), index_on_2.get(entry, []))
        return [yourstructure[i] for i in entries]
    else:
        return [yourstructure[i] for i in index_on_3.get(entry, [])]

エントリが複数のタプルに一致する可能性があるため、これは常にリストを返すことに注意してください。ルックアップが文字列の場合、最初の 2 つのインデックスのみを使用し、それ以外の場合は 3 番目のみを使用します。

または、エントリの種類を気にしないより一般的な解決策は、3 つの個別の変数ではなく、インデックスのリストを作成することです。

indexes = [defaultdict(list) for _ in range(3)]

for i, values in enumerate(yourstructure):
    for index, val in zip(indexes, values):
        index[val].append(i)

ルックアップは次のようになります。

def lookup(entry):
    entries = chain(*[index.get(entry, []) for index in indexes])
    return [yourstructure[i] for i in entries]

要素を追加または削除すると、インデックスが最新の状態に保たれるクラスにこれをすべてまとめることができます。

于 2012-10-15T10:28:05.987 に答える
1

簡単で単純な方法は次のとおりです。

>>> your_list
[('a', 'aA', 53), ('b', 'bb', 21), ('c', 'cc', 234), ('d', 'de', 76)]
>>> def get_tuple(list_of_tuples, elem):
...     for item in list_of_tuples:
...             if elem in item:
...                     return item
...     return False
... 
>>> get_tuple(your_list, 'a')
('a', 'aA', 53)
>>> get_tuple(your_list, 'cc')
('c', 'cc', 234)

ただし、指定していませんが、1 つの要素が複数のタプルにある場合はどうなるでしょうか。リストの「a」に対して何を返す必要がありますか

[('a','aA', 53),
('b','bb', 21),
('a','ca', 234),
..]
于 2012-10-15T10:28:12.977 に答える
1

検索を続けるために、O(1)これらのタプルから次のような辞書を作成できます。

In [20]: lis=[('a','aA', 53),
   ....:  ('b','bb', 21),
   ....:  ('c','cc', 234),
   ....:  ('d','de', 76)]

In [22]: dic=dict((y,x) for x in lis for y in x)

In [23]: dic

Out[23]: 
{21: ('b', 'bb', 21),
 53: ('a', 'aA', 53),
 76: ('d', 'de', 76),
 234: ('c', 'cc', 234),
 'a': ('a', 'aA', 53),
 'aA': ('a', 'aA', 53),
 'b': ('b', 'bb', 21),
 'bb': ('b', 'bb', 21),
 'c': ('c', 'cc', 234),
 'cc': ('c', 'cc', 234),
 'd': ('d', 'de', 76),
 'de': ('d', 'de', 76)}

どんなアイテムでも簡単に検索できるようになりました:

In [24]: dic.get('a','not found')
Out[24]: ('a', 'aA', 53)

In [25]: dic.get('aA','not found')
Out[25]: ('a', 'aA', 53)

In [26]: dic.get('21','not found')
Out[26]: 'not found'

In [27]: dic.get(21,'not found')
Out[27]: ('b', 'bb', 21)
于 2012-10-15T10:33:52.727 に答える