4

「e」が単語に現れる回数を数えようとしています。

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」で終わる場合を除いて、正常に機能しているようです。その'e'を2回カウントします。理由はわかりません。何か助けはありますか?

私は自分のコードがずさんなものかもしれないことを知っています、私は初心者です!私はただ起こっていることの背後にある論理を理解しようとしています。

4

9 に答える 9

13
>>> word = 'eeeooooohoooooeee'
>>> word.count('e')
6

なぜこれではないのですか?

于 2010-12-30T14:58:43.183 に答える
12

他の人が言及しているように、あなたは簡単なでテストを実装することができますword.count('e')。これを単純な演習として行っていない限り、これは車輪の再発明を試みるよりもはるかに優れています。

コードの問題は、最後にインデックス-1をテストしているため、最後の文字が2回カウントされることです。これは、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
于 2010-12-30T14:58:42.380 に答える
1

なぜ単純ではないのですか

def has_no_e(word):
    return sum(1 for letter in word if letter=="e")
于 2010-12-30T14:54:18.390 に答える
1

whileループを使用する必要はありません。文字列は、Pythonのforループで使用できます。

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")
于 2010-12-30T14:57:25.773 に答える
1

問題は、繰り返しの「文字」の最後の値が「0」であることです。これが発生した場合は、次のようになります。

  word[letters-1]

つまり、python では「単語の最後の文字」を意味する word[-1] を見ます。
したがって、実際には正しく数えており、最後の文字が「e」の場合は「ボーナス」を追加しています。

于 2010-12-30T14:58:55.753 に答える
1

letterse で終わると、 1回デクリメントが多すぎるため、2回カウントされます( while をループし、 while をループletters >= 0する必要があるためletters > 0)。ゼロに達したら、単語の最後の文字に対応する==をlettersチェックします。word[letters-1]word[-1]

于 2010-12-30T14:59:43.057 に答える
1

これらの提案された解決策の多くはうまく機能します。

Python では、list[-1] はリストの最後の要素を返すことに注意してください。

したがって、元のコードでは、文字 >= 0 で制約された while ループで word[letters-1] を参照していた場合、単語の末尾にある 'e' を 2 回カウントします (文字が長さのときに 1 回)。文字が 0 の場合は 1 回目と 2 回目)。

たとえば、私の単語が「Pete」だった場合、コード トレースは次のようになります (各ループで word[letter] を出力した場合)。

e (単語 [3] の場合) t (単語 [2] の場合) e (単語 [1] の場合) P (単語 [0] の場合) e (単語 [-1] の場合)

これが問題を解決し、Python に関する興味深いちょっとした癖を明らかにするのに役立つことを願っています。

于 2010-12-30T15:05:44.287 に答える
1

@marcogはいくつかの優れた点を指摘しています。

それまでの間、print ステートメントを挿入することで簡単なデバッグを行うことができます -

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. eを正しく認識しています
  3. 文字列の最後まで「ラップアラウンド」しています-したがって、文字列が1つで終わる場合は余分な e
于 2010-12-30T16:50:53.947 に答える
1

本当に必要なものが '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
于 2010-12-31T16:01:55.683 に答える