Как эффективно считать псевдонимы строк? - PullRequest
0 голосов
/ 26 мая 2018

Я работаю над личным проектом, который подсчитывает количество имен, упомянутых в тексте.Я знаю, что могу сделать это с collections.Counter(), но я не уверен, как эффективно учесть псевдонимы.

Так, например, скажем, одно из имен, которые я хочу сосчитать, это "Tim", но я также хотел бы подсчитать любые псевдонимы, которые у него есть, например "Timmy" и "Timster".

У меня есть несколько строк, говорящих: "Oh Tim is going to the party?", "Yeah, my boy Timmy, wouldn't miss it, he loves to party!", "Whoa, the Timster himself is going? Count me in!"

, которые я хотел бы, чтобы все считали как переменную типа "Tim".Я знаю, что могу просто подсчитать их все по отдельности, а затем сложить все вместе.Но я чувствую, что есть лучший способ сделать это.

То есть, я хочу, чтобы мой код выглядел больше как

names = {
    'Tim':{'Tim', 'Timmy', 'Timster'},
    ... other names here.}
# add any occurrence of Tim names to Tim and other occurrences of other names to their main name.

В отличие от чего-то вроде

total_tim = Counter(tim) + Counter(timmy) + Counter(timster), etc..

для каждого имени.У кого-нибудь есть идеи, как мне поступить?

Ответы [ 3 ]

0 голосов
/ 26 мая 2018

с помощью регулярных выражений поможет решить эту проблему.

import re
your_dict = {"Tim":["Tim","Timmy","Timster"]}
s = "Oh Tim is going to the party? Yeah, my boy Timmy, wouldn't miss it, he loves to party! Whoa, the Timster himself is going? Count me in!"
for each in your_dict:
    print(each,"count = ", len(re.findall("|".join(sorted(your_dict[each],reverse=True)),s)))

Если вы хотите игнорировать регистр, просто используйте параметр re.IGNORECASE в re.findall

0 голосов
/ 26 мая 2018

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

Что хорошего в этом решении, так это то, что вам не нужно явно называть варианты.Если вы знаете начальные варианты имени этого человека, с вами все будет в порядке.

from collections import Counter
import re

TEXT = '''
    Blah Tim blah blah Timmy blah Timster blah Tim
    Blah Bill blah blah William blah Billy blah Bill Bill
'''

tim_search = '(Tim([a-z]*)?(?=\ ?))'
bill_search = '((B|W)ill([a-z]*)?(?=\ ?))'
def name_counter(regex_string): 
   return Counter([i for i, *j in re.findall(regex_string, TEXT)])

name_counter(tim_search)
Counter({'Tim': 2, 'Timmy': 1, 'Timster': 1})

name_counter(bill search)
Counter({'Bill': 3, 'Billy': 1, 'William': 1})
0 голосов
/ 26 мая 2018
from collections import Counter

TEXT = '''
    Blah Tim blah blah Timmy blah Timster blah Tim
    Blah Bill blah blah William blah Billy blah Bill Bill
'''
words = TEXT.split()

# Base names a their aliases.
ALIASES = dict(
    Tim = {'Tim', 'Timmy', 'Timster'},
    Bill = {'Bill', 'William', 'Billy'},
)

# Given any name, find its base name.
BASE_NAMES = {a : nm for nm, aliases in ALIASES.items() for a in aliases}

# All names.
ALL_NAMES = set(nm for aliases in ALIASES.values() for nm in aliases)

# Count up all names.
detailed_tallies = Counter(w for w in words if w in ALL_NAMES)

# Then build the summary counts from those details.
summary_tallies = Counter()
for nm, n in detailed_tallies.items():
    summary_tallies[BASE_NAMES[nm]] += n

print(detailed_tallies)
print(summary_tallies)

# Counter({'Bill': 3, 'Tim': 2, 'Timmy': 1, 'Timster': 1, 'William': 1, 'Billy': 1})
# Counter({'Bill': 5, 'Tim': 4})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...