Проблема здесь в вашей структуре данных.В общем, словари хороши, если вы хотите найти их.Однако, это не то, что вы делаете здесь.Вместо этого я бы посоветовал список кортежей.Итак, ваш words
будет выглядеть так:
words = [ ("very funny", 3), ("funny", 2), ("accidentally funny", 1) ]
Далее, когда вы запускаете цикл for, вы выполняете итерации по каждому символу в строке вместо каждого слова.Вместо этого вам следует перебрать значения в words
и найти количество вхождений каждого слова:
import re
total = 0
for w in words:
total += w[1] * sum(re.finditer(w[0], data))
Однако, как уже указывалось, при этом будут найдены дубликаты.Чтобы избежать этого, вы должны заказать words
в том порядке, в котором вы хотите их найти, и удалить значения, которые вы найдете в data
:
words = [ ("very funny", 3), ("accidentally funny", 1), ("funny", 2) ]
total = 0
for w in words:
total += len(list(re.finditer(w[0], data))) * w[1]
data = data.replace(w[0], '')
Однако это не очень эффективно.Если вы хотите, чтобы это работало быстрее, я бы использовал LL parser .По сути, вы бы разбили свои данные на пробелы и итерировали бы по ним, вытягивая следующие k
символов, где k
- это количество слов в самой длинной записи в words
.Вы должны объединить эти k
слова вместе, используя пробелы, и проверить, соответствуют ли они какой-либо записи в words
.В этом случае вы хотели бы использовать словарь, кстати.Вы можете сделать это следующим образом:
splitData = data.split(' \r\n')
total = 0
for i in range(0, len(splitData)):
# Longest entry in words has two words so we use i + 2
phrase = ' '.join(splitData[i:(i + 2)])
if (phrase in words):
total += words[phrase]
Конечно, это решение предполагает, что во всех ваших записях есть два слова, а это не так.Чтобы решить эту проблему, включите words
в словарь словарей, в котором словарь верхнего уровня сопоставляет фразу с количеством слов в нем:
words = {1: {"funny": 2}, 2: {"very funny": 3, "accidentally funny": 1}}
splitData = data.split(' \r\n')
total = 0
i = 0
while (i < len(splitData)):
for l, mapping in words.items():
phrase = ' '.join(splitData[i:(i + l)])
if (phrase in mapping):
total += mapping[phrase]
i += 1
continue
i++
Обратите внимание, что я добавляю l
к i
чтобы избежать дубликатовОпять же, вы можете использовать кортежи вместо словаря, чтобы установить порядок поиска.Кроме того, я использую цикл while вместо forloop, потому что вы не можете изменить значение инварианта цикла внутри цикла в Python.