Подсчет букв в слове в отладке Python - PullRequest
4 голосов
/ 30 декабря 2010

Я пытаюсь посчитать, сколько раз слово «е» появляется в слове.

def has_no_e(word):     #counts 'e's in a word
    letters = len(word)
    count = 0
    while letters >= 0:
        if word[letters-1] == 'e':
            count = count + 1
        letters = letters - 1
    print count

Кажется, что работает нормально, за исключением случаев, когда слово заканчивается на 'e'. Он будет считать, что «е» дважды. Понятия не имею почему. Любая помощь?

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

Ответы [ 9 ]

11 голосов
/ 30 декабря 2010
>>> word = 'eeeooooohoooooeee'
>>> word.count('e')
6

Почему бы не это?

10 голосов
/ 30 декабря 2010

Как уже упоминалось, вы можете реализовать тест с помощью простого word.count('e').Если вы не делаете это как простое упражнение, это гораздо лучше, чем пытаться заново изобрести колесо.

Проблема с вашим кодом состоит в том, что он подсчитывает последний символ дважды, потому что вы тестируете индексконец, который в Python возвращает последний символ в строке.Исправьте это, изменив while letters >= 0 на while letters > 0.

Существуют и другие способы привести ваш код в порядок (если это упражнение в обучении):

  • Pythonхороший способ перебора строки, используя цикл for.Это гораздо более кратко и проще для чтения, чем использование цикла while и ведение собственной переменной-счетчика.Как вы уже видели здесь, добавление сложности приводит к ошибкам.Сохраняйте это простым.
  • Большинство языков предоставляют оператор +=, который для целых чисел добавляет сумму к переменной.Это более кратко, чем count = count + 1.
  • Используйте параметр, чтобы определить, какой символ вы считаете, чтобы сделать его более гибким.Определите аргумент по умолчанию для использования char='e' в списке параметров, когда у вас есть очевидное значение по умолчанию.
  • Выберите более подходящее имя для функции.Имя has_no_e() заставляет читателя думать, что код проверяет, нет ли у кода e, но на самом деле он подсчитывает вхождения e.

Собрав все это вместе, мы получим:

def count_letter(word, char='e'):
    count = 0
    for c in word:
        if c == char:
            count += 1
    return count

Некоторые тесты:

>>> count_letter('tee')
2
>>> count_letter('tee', 't')
1
>>> count_letter('tee', 'f')
0
>>> count_letter('wh' + 'e'*100)
100
1 голос
/ 31 декабря 2010

Если вы действительно хотите иметь has_no_e, то следующее может быть более уместным, чем подсчет e и последующая проверка на ноль,

def has_no_e(word):
  return 'e' not in word

>>> has_no_e('Adrian')
True
>>> has_no_e('test')
False
>>> has_no_e('NYSE')
True

Если вы хотите проверить, что E тоже нет,

def has_no_e(word):
  return 'e' not in word.lower()

>>> has_no_e('NYSE')
False
1 голос
/ 30 декабря 2010

@ Marcog делает несколько отличных очков;

тем временем вы можете выполнить простую отладку, вставив операторы печати -

def has_no_e(word):
    letters = len(word)
    count = 0
    while letters >= 0:
        ch = word[letters-1]         # what is it looking at?
        if ch == 'e':
            count = count + 1
            print('{0} <-'.format(ch))
        else:
            print('{0}'.format(ch))
        letters = letters - 1
    print count

тогда

has_no_e('tease')

возвращает

e <-
s
a
e <-
t
e <-
3

из которого вы можете видеть, что

  1. вы проходите строку в обратном порядке
  2. правильно распознает е
  3. вы 'оборачиваетесь' до конца строки - отсюда и дополнительная буква e, если ваша строка оканчивается на один
1 голос
/ 30 декабря 2010

Многие из этих предложенных решений будут работать нормально.

Знайте, что в Python list [-1] вернет последний элемент списка.

Итак, в вашем исходном кодекогда вы ссылались на слово [letters-1] в цикле while, ограниченном буквами> = 0, вы посчитали бы 'e' в конце слова дважды (один раз, когда буквы были длиной-1, и второй раз, когдабукв было 0).

Например, если бы мое слово было «Пит», ваша трассировка кода выглядела бы так (если бы вы печатали слово [буква] каждый цикл.

e (для слова[3]) t (для слова [2]) e (для слова [1]) P (для слова [0]) e (для слова [-1])

Надеюсь, это поможет прояснить ситуациюи раскрыть интересную небольшую причуду о Python.

1 голос
/ 30 декабря 2010

Он будет учитываться дважды, когда заканчивается буквой e, потому что вы уменьшаете letters на один раз слишком много (потому что вы циклируете пока letters >= 0, и вы должны циклически пока letters > 0). Когда letters достигает нуля, вы проверяете word[letters-1] == word[-1], что соответствует последнему символу в слове.

1 голос
/ 30 декабря 2010

Проблема в том, что последнее значение 'letters' в вашей итерации равно '0', и когда это происходит, вы смотрите:

  word[letters-1]

, то есть вы смотрите на слово [-1]что в python означает «последняя буква слова».
, поэтому вы действительно правильно рассчитываете и добавляете «бонус», если последняя буква - «е».

1 голос
/ 30 декабря 2010

Вам не нужно использовать цикл while.Строки можно использовать для циклов в Python.

def has_no_e(word):
    count = 0
    for letter in word:
        if letter == "e":
            count += 1
    print count

или что-то более простое:

def has_no_e(word):
    return sum(1 for letter in word if letter=="e")
1 голос
/ 30 декабря 2010

Почему бы не просто

def has_no_e(word):
    return sum(1 for letter in word if letter=="e")
...