Пересечение двух словарей в Python

Я работаю над поисковой программой по инвертированному индексу. Сам индекс является словарем, ключи которого являются условиями и чьи значения являются самостоятельно словарями коротких документов с Идентификационными номерами как ключи и их текстовое содержание как значения.

Чтобы работать 'И' искать два условия, я таким образом должен пересечься, их регистрации перечисляет (словари). Что такое ясное (не обязательно чрезмерно умный) способ сделать это в 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
...
61
задан 1 September 2013 в 04:13

2 ответа

Ваш вопрос не достаточно точен для предоставления единственного ответа.

1. Ключевое Пересечение

, Если Вы хотите пересечься ID с из сообщений ( кредиты к James) делает:

common_ids = p1.keys() & p2.keys()

Однако, если Вы хотите выполнить итерации документов, необходимо рассмотреть, какое сообщение имеет приоритет, я предполагаю, что это p1. Выполнить итерации документов для common_ids, collections.ChainMap будет самым полезным:

from collections import ChainMap
intersection = {id: document
                for id, document in ChainMap(p1, p2)
                if id in common_ids}
for id, document in intersection:
    ...

Или если Вы не хотите создавать отдельный intersection словарь:

from collections import ChainMap
posts = ChainMap(p1, p2)
for id in common_ids:
    document = posts[id]

2. Пересечение объектов

, Если Вы хотите пересечься объекты из сообщений, что означает соответствовать ID с и документы, использует код ниже ( кредиты к DCPY). Однако это только полезно при поиске дубликатов в терминах.

duplicates = dict(p1.items() & p2.items())
for id, document in duplicates:
    ...

3. Выполните итерации более чем [1 111] 'И' p2.

В случае, если, когда" 'И' поиск " и использование iter Вы означали искать оба , сообщения с другой стороны collections.ChainMap является лучшим для итерации по (почти) всем объектам в нескольких сообщениях:

from collections import ChainMap
for id, document in ChainMap(p1, p2):
    ...
0
ответ дан 31 October 2019 в 14:42
def two_keys(term_a, term_b, index):
    doc_ids = set(index[term_a].keys()) & set(index[term_b].keys())
    doc_store = index[term_a] # index[term_b] would work also
    return {doc_id: doc_store[doc_id] for doc_id in doc_ids}

def n_keys(terms, index):
    doc_ids = set.intersection(*[set(index[term].keys()) for term in terms])
    doc_store = index[term[0]]
    return {doc_id: doc_store[doc_id] for doc_id in doc_ids}

In [0]: index = {'a': {1: 'a b'}, 
                 'b': {1: 'a b'}}

In [1]: two_keys('a','b', index)
Out[1]: {1: 'a b'}

In [2]: n_keys(['a','b'], index)
Out[2]: {1: 'a b'}

я рекомендовал бы изменить Ваш индекс от

index = {term: {doc_id: doc}}

к двум индексам один для условий и затем отдельного индекса для содержания значений

term_index = {term: set([doc_id])}
doc_store = {doc_id: doc}

тот способ, которым Вы не храните несколько копий тех же данных

0
ответ дан 31 October 2019 в 14:42

Другие вопросы по тегам:

Похожие вопросы: