2015-10-06 3 views
0

Я пытаюсь подсчитать количество случаев словесных сокращений в некоторых речах, которые я собрал. Одна конкретная речь выглядит так:Количество вхождений элементов в строке из списка?

speech = "I've changed the path of the economy, and I've increased jobs in our own 
home state. We're headed in the right direction - you've all been a great help." 

Итак, в этом случае я бы хотел сосчитать четыре (4) сокращения. У меня есть список сокращений, и вот некоторые из первых членов:

contractions = {"ain't": "am not; are not; is not; has not; have not", 
"aren't": "are not; am not", 
"can't": "cannot",...} 

Мой код выглядит примерно так, чтобы начать с:

count = 0 
for word in speech: 
    if word in contractions: 
     count = count + 1 
print count 

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

+5

for word in speech.split (''): – Monkpit

+0

Я не понимаю, что делают значения в вашем dict, у вас есть dict btw not a list –

+0

В моем ответе я добавил много вещей, которые должен предоставить вам некоторые дополнительные услуги. – colidyre

ответ

5

Использование str.split() разделить вашу строку на пробельных:

for word in speech.split(): 

Это разделится на произвольной пробельных; это означает пробелы, вкладки, символы новой строки и еще несколько экзотических пробельных символов и любое количество из них в строке.

Вам может понадобиться строчных ваших слов, используя str.lower() (иначе Ain't не будут найдены, например), и полоса пунктуации:

from string import punctuation 

count = 0 
for word in speech.lower().split(): 
    word = word.strip(punctuation) 
    if word in contractions: 
     count += 1 

Я использую str.strip() method здесь; он удаляет все, что находится в string.punctuation string от начала и до конца слова.

1

Вы повторяете строку. Таким образом, элементы являются символами. Чтобы получить слова из строки, вы можете использовать наивные методы, такие как str.split(), что делает это для вас (теперь вы можете перебирать список строк (слова, разделенные по аргументу str.split(), по умолчанию: split on whitespace). Существует даже re.split(), который является более мощным. Но я не думаю, что вам нужно разделив текст с регулярными выражениями.

То, что вы должны сделать, по крайней мере, в нижнем регистре вашу строку с str.lower() или поставить все возможные вхождений (также с заглавными буквами) в словаре. Я настоятельно рекомендую первый вариант: последний не является практически осуществимым. Удаление препинания также является обязанностью для этого, но это все еще наивно. Если вам нужен более сложный метод, вам нужно разделить текст с помощью токенизатора слов. NLTK - хорошая отправная точка для этого, см. раздел nltk tokenizer. Но я твердо чувствую, что эта проблема не ваша главная или не влияет на вас в самом деле в решении вашего вопроса. :)

speech = """I've changed the path of the economy, and I've increased jobs in our own home state. We're headed in the right direction - you've all been a great help.""" 
# Maybe this dict makes more sense (list items as values). But for your question it doesn't matter. 
contractions = {"ain't": ["am not", "are not", "is not", "has not", "have not"], "aren't": ["are not", "am not"], "i've": ["i have", ]} # ... 

# with re you can define advanced regexes, but maybe 
# from string import punctuation (suggestion from Martijn Pieters answer 
# is still enough for you) 
import re 

def abbreviation_counter(input_text, abbreviation_dict): 
    count = 0 
    # what you want is a list of words. str.split() does this job for you. 
    # " " is default and you can also omit this. But if you really need better 
    # methods (see answer text abover), you have to take a word tokenizer tool 
    # or have to write your own. 
    for word in input_text.split(" "): 
     # and also clean word (remove ',', ';', ...) afterwards. The advantage of 
     # using re over `from string import punctuation` is that you have more 
     # control in what you want to remove. That means that you can add or 
     # remove easily any punctuation mark. It could be very handy. It could be 
     # also overpowered. If the latter is the case, just stick to Martijn Pieters 
     # solution. 
     if re.sub(',|;', '', word).lower() in abbreviation_dict: 
      count += 1 

    return count 

print abbrev_counter(speech, contractions) 
2 # yeah, it worked - I've included I've in your list :) 

Это Литты немного расстраивает, чтобы дать ответ на то же время, как это делает Мартейн Питерс;), но я надеюсь, что я до сих пор породил некоторые значения для вас. Вот почему я отредактировал свой вопрос, чтобы дать вам несколько советов для будущей работы.

+0

Спасибо за ввод, но я перешел от этой проблемы. Однако ваше решение действительно сработало! Я просто не хотел возвращаться и переформатировать весь мой словарь «схваток» :) – blacksite

+0

Да, конечно, это всего лишь предложение. Я был бы рад получить вознаграждение за свою работу, если бы это было полезно в любом случае. :) – colidyre

+0

Я тебя уже :) – blacksite

0

A for цикл в Python выполняет итерацию по всем элементам в итерабельной. В случае строк элементы являются символами.

Вам нужно разбить строку на список (или кортеж) строк, содержащих слова. Вы можете использовать для этого .split(delimiter).

Ваша проблема довольно распространена, поэтому у Python есть ярлык: speech.split() разбивается на любое количество пробелов/вкладок/новых строк, поэтому вы получаете только свои слова в списке.

Так что ваш код должен выглядеть следующим образом:

count = 0 
for word in speech.split(): 
    if word in contractions: 
     count = count + 1 
print(count) 

speech.split(" ") тоже работает, но только расщепляется на непечатаемых, но не вкладки или новую строку, и если есть двойные пробела вы получите пустые элементы в результирующем списке.

Смежные вопросы