Python: разбить словарные значения на термины и сделать из них словарь - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть файл, который состоит из цифр - идентификаторы документов; и текст - документ:

1000 Конец света

1001 Это нормально

Необходимо создать словарь терминов и список публикаций . Словарь терминов представляет документы, просто разделенные на термины и соединенные с идентификатором документа. Термин словарь должен быть, я предполагаю (ключ: термин, значение: document_id), как это:

= 1000

world`s = 1000

end = 1000

this = 1001

is = 1001

fine = 1001

Список публикаций показывает, в каких документах находится термин, расположенный в Должно выглядеть так:

Это = 1000 1001

= 1000 1001

first = 1000

Мне удалось только разделив документ на термины (даже не знаю, правильно ли я это сделал). Что и как делать на следующем шаге?

Python код

#Open and read documents file
docLine = codecs.open('sample.txt', 'r', 'utf8').read().splitlines()

#Empty dictionary
doc_dictionary = {}

#Split every line in id (keys) and documents (val) to save as dictionary
for document in docLine:
    (key, val) = re.split(r'\t+', document)
    doc_dictionary[key] = val
print("Documents")
print(doc_dictionary)

#Splits documents into words (terms)
print("") 
print("Words")
words = {key: [(val) for val in value.split()] for key, value in doc_dictionary.items()}
print(words)

Результат

Документы {

'1000 ':' Project Gutenberg - книга о гордости и предубеждении, автор Джейн Остин,

'1001': «Эта электронная книга предназначена для использования кем угодно и где угодно и практически без ограничений. Вы можете скопировать его, отдать или повторно использовать в соответствии с условиями лицензии Project Gutenberg, прилагаемой к этой электронной книге, или через Интернет по адресу www.gutenberg.org ', et c.

Words {

'1000': ['The', 'Project', 'Gutenberg', 'EBook', 'of', 'Pride', 'и', 'Prejudice,', 'by', 'Джейн', 'Остин'],

'1001': ['This', 'eBook', 'is', 'for', 'the', 'use', 'of', 'any ',' где-нибудь ',' в ',' нет ',' стоимость ',' и ',' с ',' почти ',' нет ',' ограничения ',' что угодно. ',' Вы ',' может ' , «копировать», «это», «дать», «это», «прочь», «или», «повторно использовать», «это», «под», «the», «условия», «из ',' the ',' Project ',' Gutenberg ',' License ',' includes ',' with ',' this ',' eBook ',' or ',' online ',' at ',' www.gutenberg.org '],

Ответы [ 2 ]

1 голос
/ 03 апреля 2020

По вашему вопросу кажется, что вы пытаетесь поменять местами ключи и значения вновь сгенерированного dict. Это называется индексирование , это то, что вы видите в конце книги и как поисковые машины быстро доставляют результаты.

Вместо создания нескольких словарей, вы можете сделать это за одну итерацию:

from collections import defaultdict

def normalize(line, pattern=re.compile(r"\W*\s+\W*")):
    # Use pattern to split line and trim non-word characters and set to lowercase
    return map(str.lower, pattern.split(line.strip(".!+,")))

index = defaultdict(set)
for document in docLine:
    key, value = re.split(r'\t+', document, 1)  # Split line into key and text parts
    for word in normalize(value):               # Normalize words to be used as index
        index[word].add(key)                    # Add key to word's set

Вывод

{'almost': {'1001'},
 'and': {'1001', '1000'},
 'anyone': {'1001'},
 'anywhere': {'1001'},
 'at': {'1001'},
 'austen': {'1000'},
 'away': {'1001'},
 'by': {'1000'},
 'copy': {'1001'},
 'cost': {'1001'},
 'ebook': {'1001', '1000'},
 'for': {'1001'},
 'give': {'1001'},
 'gutenberg': {'1001', '1000'},
 'included': {'1001'},
 'is': {'1001'},
 'it': {'1001'},
 'jane': {'1000'},
 'license': {'1001'},
 'may': {'1001'},
 'no': {'1001'},
 'of': {'1001', '1000'},
 'online': {'1001'},
 'or': {'1001'},
 'prejudice': {'1000'},
 'pride': {'1000'},
 'project': {'1001', '1000'},
 're-use': {'1001'},
 'restrictions': {'1001'},
 'terms': {'1001'},
 'the': {'1001', '1000'},
 'this': {'1001'},
 'under': {'1001'},
 'use': {'1001'},
 'whatsoever': {'1001'},
 'with': {'1001'},
 'www.gutenberg.org': {'1001'},     # Notice no trailing period.
 'you': {'1001'}}

Пожалуйста, посмотрите мой Repl с полным примером.

Это использует defaultdict, который гарантирует, что каждый новый ключ имеет определенный c тип (в данном случае set). настроить основной словарь.

1 голос
/ 03 апреля 2020

Я хотел бы l oop через словарь, который вы создали:

result = {}
for key, list in words.items():
    for elem in list:
        if elem in result:
            if not key in result[elem]:
                result[elem].append(key)
        else:
            result[elem] = [key]

Я попробовал это с

words = {'1000': ['the', 'world', 'the'],
         '1001': ['the', 'party']}

и результат:

{'the': ['1000', '1001'], 'world': ['1000'], 'party': ['1001']}

для поиска списка терминов в словаре результатов вы можете использовать это:

for word in to_find:
    if word in result:
        print(word + ': ' + " ".join(result[word]))
    else:
        print(word + ': not found in dict')

пример ввода: to_find = ['the', 'party', 'car'] дает такой вывод:

: 1000 1001

партия: 1001

автомобиль: не найден в dict

...