Как подсчитать вхождение каждого элемента из списка в строку в Python? - PullRequest
1 голос
/ 26 сентября 2019

Скажите, у меня есть следующий список.

food_list = ['ice cream', 'apple', 'pancake', 'sushi']

И я хочу найти каждый элемент в этом списке в следующей строке.

my_str = 'I had pancake for breakfast this morning, while my sister ate some apples. I brought one apple and ate it on my way to work. My coworker was having his birthday today, and he gave us free ice cream. It was the best ice cream I had this year.'

my_str = my_str.lower()

Iхотите посчитать количество элементов в строке.

ice cream : 2, apple: 1, pancake: 1, sushi:0

Обратите внимание, что яблоко считается только один раз, потому что apples не должно учитываться.Я не могу разделить его по пробелам из-за таких элементов, как ice cream.

Я думал о том, чтобы заменить слово в списке чем-то и посчитать это позже, но это очень медленно (применительно к большим данным).И мне интересно, есть ли лучшее решение.

for word in food_list:
    find_word = re.sub(r'\b'+word+r'\b', "***", my_str)
    count_word = find_word.count("***")
    print(word+": "+str(count_word))

Надеюсь, это достаточно ясно.Спасибо

Ответы [ 5 ]

1 голос
/ 26 сентября 2019

Вы можете найти точное слово в строке, используя re.finditer

import re


food_list = ['ice cream', 'apple', 'pancake', 'sushi']

my_str = 'I had pancake for breakfast this morning, while my sister ate some apples. I brought one apple and ate it on my way to work. My coworker was having his birthday today, and he gave us free ice cream. It was the best ice cream I had this year.'
my_str = my_str.lower()


output = {}
for word in food_list:
   count = sum(1 for _ in re.finditer(r'\b%s\b' % re.escape(word), my_str))
   output[word] = count

Вывод:

for word, count in output.items():
    print(word, count)

>>> ice cream 2
>>> apple 1
>>> pancake 1
>>> sushi 0
1 голос
/ 26 сентября 2019

Используйте re.findall с пониманием речи:

import re

cnt = {k: len(re.findall(r'\b{}\b'.format(k), my_str)) for k in food_list}

Вывод:

{'apple': 1, 'ice cream': 2, 'pancake': 1, 'sushi': 0}
0 голосов
/ 26 сентября 2019

вы можете запустить поиск совпадения строки, отрегулировав начальную позицию:

def find_all(a_str, sub):
start = 0
counter = 0
while True:
    start = a_str.find(sub, start)
    if start == -1: return
    counter += 1
    yield start
    start += len(sub) # use start += 1 to find overlapping matches

if __name__ == "__main__":
    food_list = ['ice cream', 'apple', 'pancake', 'sushi']
    my_str = 'I had pancake for breakfast this morning, while my sister ate some apples. I brought one apple and ate it on my way to work. My coworker was having his birthday today, and he gave us free ice cream. It was the best ice cream I had this year.'
    my_str = my_str.lower()
    counts = {}
    for item in food_list:
        counts.update({item: len(list(find_all(my_str, item)))})
    print(counts)
0 голосов
/ 26 сентября 2019

В одном сканировании регулярное выражение попытается найти все совпадения, а затем подсчитать количество совпадений для всех совпадений, найденных в строке.

food_list = ['ice cream', 'apple', 'pancake', 'sushi']
regex = '|'.join([r'\b'+ item + r'\b' for item in food_list])
my_str = 'I had pancake for breakfast this morning, while my sister ate some apples. I brought one apple and ate it on my way to work. My coworker was having his birthday today, and he gave us free ice cream. It was the best ice cream I had this year.'
my_str = my_str.lower()
all_matches = re.findall(r'%s' % regex, my_str)
count_dict = {item: all_matches.count(item) for item in food_list}
0 голосов
/ 26 сентября 2019

Вы можете просто использовать регулярное выражение, которое учитывает границы слов при понимании словаря:

>>> import re
>>> {food: sum(1 for match in re.finditer(r"\b{}\b".format(food), my_str)) for food in food_list}
{'pancake': 1, 'sushi': 0, 'apple': 1, 'ice cream': 2}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...