2014-01-07 3 views
0
sentence2 = raw_input("Enter the sentence on the StringLab3 WS: ") 

sentence.split(sentence2) 
for word in default_sentence: 
    if word == (chr(84)+chr(104)+chr(101)) or (chr(116)+chr(104)+chr(101)): 
     words += 1 

print "The amounf of times 'the' or 'The' appear is a total of", words, "times." 

Это то, что у меня есть сейчас, выход в настоящее время 961 для предложения:Python - Как узнать, сколько раз пользователь сказал слово «» или «»

Это является день национального освящения. И я уверен, что в этот день мои коллеги-американцы ожидают, что после моего вступления в Президиум я обращусь к ним с откровенностью и решением, которое побуждает нынешнее положение нашего народа. Это прежде всего время говорить правду, всю правду, откровенно и смело. Нам также не нужно уклоняться от честных ситуаций в нашей стране сегодня. Эта великая нация будет терпеть, как она пережила, оживет и будет процветать. Поэтому, прежде всего, позвольте мне заявить о своей твердой уверенности в том, что единственное, чего мы должны бояться, - это сам страх, безымянный, необоснованный, необоснованный террор, который парализует необходимые усилия для преобразования отступления в аванс. В каждый темный час нашей национальной жизни руководство откровенности и бодрости встречало это понимание и поддержку самих людей, что необходимо для победы. И я убежден, что вы снова окажете поддержку лидерству в эти критические дни.

Предполагается, что пользователь вводит это. Любой совет?

+3

Почему вы используете 'CHR()' вместо того, чтобы просто с помощью буквального '«»'? – Barmar

+0

Коренная проблема здесь в том, что 'word == 'the' or 'The'' не означает, что вы думаете, что это так. (Я удалил лишнюю обфускацию, чтобы сделать ti clearer.) Вы хотите 'word in ('the', 'The')'. Есть около 500 вопросов о SO, которые объясняют, почему. – abarnert

+2

Да, но проблема 'or' - распространенная ошибка. Я вижу примеры этого на SO каждые несколько дней. – Barmar

ответ

2

Я рекомендовал бы это:

map(lambda word: word.lower(), paragraph.split()).count("the") 

Выход:

>>> paragraph = "This is a day of national consecration. And I am certain that on this day my fellow Americans expect that on my induction into the Presidency, I will address them with a can 
dor and a decision which the present situation of our people impels. This is preeminently the time to speak the truth, the whole truth, frankly and boldly. Nor need we shrink from honestly f 
acing conditions in our country today. This great Nation will endure, as it has endured, will revive and will prosper. So, first of all, let me assert my firm belief that the only thing we h 
ave to fear is fear itself, nameless, unreasoning, unjustified terror which paralyzes needed efforts to convert retreat into advance. In every dark hour of our national life, a leadership of 
frankness and of vigor has met with that understanding and support of the people themselves which is essential to victory. And I am convinced that you will again give that support to leader 
ship in these critical days." 
>>> map(lambda word: word.lower(), paragraph.split()).count("the") 
7 

Поскольку мое решение может выглядеть странно, вот небольшое объяснение слева направо:

map(function, target): Это относится функция для всех элементов target, таким образом, target должна быть списком или другим итерируемым. В этом случае мы отображение lambda функцию, которая может быть немного страшно, так что читайте ниже о том, что

.lower(): принимает нижний случай любой строки его применительно к, word в этом случае. Это делается для того, чтобы все «The», «The», «THE», «ThE» и т. Д. Считались

.split(): Это разбивает строку (paragraph) на список разделителем, поставляемым в скобка. В случае без разделителя (такого как этот) пространство считается разделителем. Обратите внимание, что последовательные разделители сосредоточены, когда разделитель отсутствует.

.count(item): Здесь подсчитываются экземпляры item в списке, к которому он применяется. Обратите внимание, что это не самый эффективный способ подсчета вещей (должен идти REGEX если вы о скорости)

Страшная функцию лямбда:

лямбда-функции не так легко объяснить или понять. Мне понадобилось немало времени, чтобы понять, что они собой представляют и когда они полезны. I found this tutorial, чтобы быть весьма полезным.

Моя лучшая попытка в tl; dr - лямбда-функции - это небольшие анонимные функции, которые можно использовать для удобства.Я знаю, что это, в лучшем случае, неполный, но я думаю, что это должно быть достаточно для охвата этого вопроса

+0

в Python3, 'map' возвращает объект' map', который не содержит метод '.count'. Вместо этого сделайте 'len ([слово в слово на карте (lambda word: word.lower(), paragraph.split()), если слово ==" the "])' на Python3 –

+0

Полностью переписать код OP не собирается помогите ему или другим читателям понять ошибки, которые он совершил. – Barmar

+2

Зачем вообще отображать «нижний»? Просто «нижний» весь абзац перед расщеплением: 'paragraph.lower(). Split(). Count ('the')' намного проще. – abarnert

1

Проблемы эта линия:

if word == (chr(84)+chr(104)+chr(101)) or (chr(116)+chr(104)+chr(101)): 

Сравнение в большинстве языков программирования не может быть сокращено, как они могут на английском языке, вы не можете писать «равен а или в», как сокращенно «равен A или равно B», вам нужно написать это:

if word == (chr(84)+chr(104)+chr(101)) or word == (chr(116)+chr(104)+chr(101)): 

То, что вы написали разобран как:

if (word == (chr(84)+chr(104)+chr(101))) or (chr(116)+chr(104)+chr(101)): 

Поскольку второе выражение в or всегда верно (это строка, и все непустые строки являются истинными), то if всегда удается, поэтому рассчитывать все слова, а не только the и The.

Там также никаких оснований использовать этот многословный chr() синтаксис, просто написать:

if word == "the" or word == "The": 

Есть другие ошибки в коде. split линия должна быть:

default_sentence = sentence2.split(); 
1

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

#!/usr/bin/env python 
import re 
input_string = raw_input("Enter your string: "); 
print("Total occurences of the word 'the': %d"%(len(re.findall(r'\b(T|t)he\b', input_string)),)); 

и если вы хотите, чтобы это было чувствительно к регистру вызова re.findall может просто быть изменены в re.findall(r'\bthe\b', input_string, re.I)

+0

Это именно то, как я бы это сделал, но он медленнее, чем некоторые другие ответы уже получили ответы. Я считаю, что это самый чистый, но YMMV. Я думаю, что самая быстрая реализация вероятна 'sum ([1 для слова в input_string.lower(). Split(), если слово ==" the "])' –

+0

@adsmith: я готов поставить bet 'list.count' is быстрее, чем вызов 'sum' в понимании списка. И, конечно, это проще и читаемо для загрузки. – abarnert

+1

Да, это медленнее, но я прыгаю при любой возможности злоупотреблять регулярными выражениями: P – raser

1

причина ваш код не работает, потому что вы написали

if word == (chr(84)+chr(104)+chr(101)) or (chr(116)+chr(104)+chr(101)): 
# evaluates to: if word == "The" or "the": 
# evaluates to: if False or "the": 
# evaluates to: if "the": 

Вместо

if (word == (chr(84)+chr(104)+chr(101))) or (word == (chr(116)+chr(104)+chr(101))): 
# evaluates to: if (word == "The") or (word == "the") 

Что еще более важно, так как Barmar указал, используя строковый литерал 'the' является много более читаемым.

Таким образом, вы можете что-то вроде этого:

count = 0 
for word in default_sentence.split(): 
    if word == 'the' or word == 'The': 
     count += 1 

wnnmaw имеет эквивалентный Однострочник, который работает почти так же хорошо. map(lambda word: word.lower()) не совсем работает, потому что по спецификации OP мы хотим только 'the' и 'The', а не 'THE'.

+2

Вам нужно инициализировать цикл' count' _outside_. – Barmar

+0

Спасибо, я исправил его сейчас. –

4

Простейшая реализация, и, вероятно, самым быстрым, является:

sentence.lower().split().count('the') 

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


Первая проблема связана с попыткой является то, что вы читаете введенные пользователем в переменную с именем sentence2, а затем использовать его в качестве разделителя, чтобы разделить некоторую другую переменную с именем sentence, выбрасывая результат, а затем цикл по еще одной переменной с именем default_sentence. Это не сработает. Python не угадает, что вы имеете в виду только потому, что имена переменных похожи. Вы должны написать эти первые три строки следующим образом:

Вторая проблема заключается в том, что ваше выражение or не означает, что вы думаете, что оно делает. Это объясняется десятками других вопросов; вы можете начать с What's going on with my if else statement и, если это не объясняет это, см. ссылки и дубликаты оттуда.

Если решить обе эти проблемы, ваш код на самом деле работает:

sentence = raw_input("Enter the sentence on the StringLab3 WS: ") 
default_sentence = sentence.split() 
words = 0 
for word in default_sentence: 
    if word in ((chr(84)+chr(104)+chr(101)), (chr(116)+chr(104)+chr(101))): 
     words += 1 

print "The amounf of times 'the' or 'The' appear is a total of", words, "times." 

Я не знаю, почему все остальные чрезмерно усложнять это во имя эффективности, путем замены count с явным sum по понятию или с использованием регулярных выражений или с использованием map для вызова lower после разделения, а не раньше или ... но они фактически замедляют работу, а также труднее читать. Который, как правило, в случае с микро-оптимизации, как это ... Например:

In [2829]: %timeit paragraph.lower().split().count('the') 
100000 loops, best of 3: 14.2 µs per loop 
In [2830]: %timeit sum([1 for word in paragraph.lower().split() if word == 'the']) 
100000 loops, best of 3: 18 µs per loop 
In [2831]: %timeit sum(1 for word in paragraph.lower().split() if word == 'the') 
100000 loops, best of 3: 17.8 µs per loop 
In [2832]: %timeit re.findall(r'\bthe\b', paragraph, re.I) 
10000 loops, best of 3: 38.3 µs per loop 
In [2834]: %timeit list(map(lambda word: word.lower(), paragraph.split())).count("the") 
10000 loops, best of 3: 49.6 µs per loop