89

私は転置インデックスの検索プログラムに取り組んでいます。索引自体は辞書であり、そのキーは用語であり、その値自体は短い文書の辞書であり、ID 番号がキーで、そのテキスト コンテンツが値です。

したがって、2 つの用語の「AND」検索を実行するには、それらの投稿リスト (辞書) を交差させる必要があります。Pythonでこれを行うための明確な(必ずしも過度に賢いとは限らない)方法は何ですか? 私はそれを長い道のりで試すことから始めましたiter:

p1 = index[term1]  
p2 = index[term2]
i1 = iter(p1)
i2 = iter(p2)
while ...  # not sure of the 'iter != end 'syntax in this case
...
4

10 に答える 10

116

一般に、Python で辞書の共通部分を作成するには、まず&演算子を使用して辞書キーの集合の共通部分を計算します (辞書キーはPython 3 では集合のようなオブジェクトです)。

dict_a = {"a": 1, "b": 2}
dict_b = {"a": 2, "c": 3} 

intersection = dict_a.keys() & dict_b.keys()  # {'a'}

Python 2 では、辞書のキーを自分でセットに変換する必要があります。

keys_a = set(dict_a.keys())
keys_b = set(dict_b.keys())
intersection = keys_a & keys_b

次に、キーの交差が与えられたら、必要に応じて値の交差を構築できます。ここで選択を行う必要があります。集合交差の概念では、関連付けられた値が異なる場合に何をすべきかがわからないためです。(これがおそらく、&交差演算子が Python の辞書に対して直接定義されていない理由です)。

この場合、同じキーの値が等しいように聞こえるので、辞書の 1 つから値を選択するだけです。

dict_of_dicts_a = {"a": {"x":1}, "b": {"y":3}}
dict_of_dicts_b = {"a": {"x":1}, "c": {"z":4}} 

shared_keys = dict_of_dicts_a.keys() & dict_of_dicts_b.keys()

# values equal so choose values from a:
dict_intersection = {k: dict_of_dicts_a[k] for k in shared_keys }  # {"a":{"x":1}}

値を結合する他の合理的な方法は、辞書内の値の型と、それらが何を表しているかによって異なります。たとえば、辞書の辞書の共有キーの値の結合も必要になる場合があります。辞書の結合は値に依存しないため、明確に定義されており、Python では|演算子を使用して取得できます。

# union of values for each key in the intersection:
dict_intersection_2 = { k: dict_of_dicts_a[k] | dict_of_dicts_b[k] for k in shared_keys }

この場合、"a"両方のキーの辞書値が同じであれば、同じ結果になります。

于 2013-09-01T00:18:58.830 に答える
87
In [1]: d1 = {'a':1, 'b':4, 'f':3}

In [2]: d2 = {'a':1, 'b':4, 'd':2}

In [3]: d = {x:d1[x] for x in d1 if x in d2}

In [4]: d
Out[4]: {'a': 1, 'b': 4}
于 2013-09-01T04:11:23.713 に答える
0

必要な値の両方を取得する単純なクラスで辞書インスタンスをラップするだけです

class DictionaryIntersection(object):
    def __init__(self,dictA,dictB):
        self.dictA = dictA
        self.dictB = dictB

    def __getitem__(self,attr):
        if attr not in self.dictA or attr not in self.dictB:
            raise KeyError('Not in both dictionaries,key: %s' % attr)

        return self.dictA[attr],self.dictB[attr]

x = {'foo' : 5, 'bar' :6}
y = {'bar' : 'meow' , 'qux' : 8}

z = DictionaryIntersection(x,y)

print z['bar']
于 2013-09-01T00:23:02.567 に答える