質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.58%

コードが理解できません

解決済

回答 4

投稿

  • 評価
  • クリップ 1
  • VIEW 591

Kyohei

score 23

環境:Python3系,MacOS

文字列中の文字の出現回数をカウントするコードなのですが、理解ができません。
わかりやすく解説のほどお願い致します。
私の解釈では、
①まず、messageに文字列を格納し、countに空の辞書を格納。
②forループ制御文でmessageに格納された文字数(空欄含む)文だけ制御文内容実装する。
内容はcount.setdefault(character,0) → countにcharacterがなければ「0」を返す。
count[character]=count[character]+1 →理解できず。。。
③最後にforループ内で実装された内容をprintで返す。

message='It was a bright cold day in April, and the clocks were striking thirteen.'
count={}


for character in message:
    count.setdefault(character , 0)
    count[character]=count[character] +1

print(count)  

   

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

面白いコードですね :)

やはり味噌はこの行でしょうか

    count[character]=count[character] +1

結論だけ申し上げますと、
「該当した文字だった場合、そのcount辞書型の該当の文字キーに1加算している」
という処理になりますね。

 TL; DR(長ったらしい解説のため、読み飛ばし可能です)

その前に、まずはこのコードの実行結果を見たほうがよいでしょうか。

{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 4, 'A': 1, 'p': 1, ',': 1, 'e': 5, 'k': 2, '.': 1}

「そりゃそうだよ! そういう結果になったよ!(半ギレ)」
と思われるかもしれませんね。

じゃあ、

    count[character]=count[character] +1

では何が行われているか、具体的に文字を入れながら見ていきましょう。

 実際に文字を一文字ずつ入れてみる

 "I" の動作

message='It was a bright cold day in April, and the clocks were striking thirteen.'
# now!   ^

    count["I"]=count["I"] +1

ご覧の通り、 count 辞書型の I というキーに、数値を1つ足してるんですね。
では、実際の数値はどうなっているでしょうか。

message='It was a bright cold day in April, and the clocks were striking thirteen.'
# now!   ^

#                     0   +1
    count["I"]=count["I"] +1

ということが行われております。もちろん count 辞書の I に 数値 0 が入っているのは、

count.setdefault(character , 0)

の行で、「 count 配列に character のキー(文字)がなかったら、 0 をセットして」
と処理しているからです。

 "t" の動作

では、 "t" はどうなってるでしょう?

message='It was a bright cold day in April, and the clocks were striking thirteen.'
# now!    ^

#                     0   +1
    count["t"]=count["t"] +1

これも1加算されます。

 続けて" "の文字

message='It was a bright cold day in April, and the clocks were striking thirteen.'
# now!     ^

#                     0   +1
    count[" "]=count[" "] +1

これも、まずは1加算されます。


これ以上書くときっとうんざりしてしまうと思うので、このへんで。
更に同じ文字があれば、もちろん以下のようになります。

message='It was a bright cold day in April, and the clocks were striking thirteen.'
# now!                         ^

#                     1   +1
    count["a"]=count["a"] +1
#   count["a"]は2になる

という事を、一文字ずつ処理しています。

 まとめ

for character in message: # messageの中を一文字ずつcharacterに入れる
    count.setdefault(character , 0) # count辞書にcharacterのキーがない場合、0を代入
    count[character]=count[character] +1 # ここに来るときには絶対にキーがあるので、辞書の要素に1加算

という具合です。

長ったらしい説明を最後まで読んでくださり、ありがとうございます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:22

    manzyunさま
    ご丁寧にありがとうございます!
    1つ質問させてください。
    messageは1つの文字列なのでcountに入るのは'It was a bright cold day in April, and the clocks were striking thirteen.'全てじゃないの?と思うのですが、なぜ1文字ずつなのでしょうか?恐れ入りますがご教授願います。。。

    キャンセル

  • 2018/11/02 15:46

    「文字列」はですね、「文字」が並んで構成されています。
    「当然じゃないか……、何言ってるんだこの人」
    と思われるかもしれませんが、Pythonの文字列データも、
    「文字で構成されたリスト型」
    として扱われます。(厳密にはstr型という文字列専用のデータ型なのですが、割愛します)

    Pythonでリスト型データについては分かりますでしょうか?
    把握しているのなら、以下のスクリプトがどんな動きをするかも分かるかと思います。

    ```
    print('It was a bright cold day in April, and the clocks were striking thirteen.'[3])
    ```

    実行しても分からなかったときのために解説を加えますと、
    上記スクリプトは
    「'It was a bright cold day in April, and the clocks were striking thirteen.' の文字列の、0から始めて3番目の文字をプリント」
    しています。

    さて、文字列がリスト型の様に使えることは分かりました。それでもなぜ、
    「countのcharacterには一文字ずつ入るのか」
    という明確な答えにはなっていませんね。

    Pythonのforは、
    「リストみたいなデータを1つずつ抽出してくれるので、文字列データも一文字ずつcharacterに入っていく」
    という動作をします。

    深く突き詰めるとそれだけでかなりの文章量になってしまいますので、今回はざっくりと説明させていただきます。(後学のヒントとして「イテレーター」「ジェネレーター」というワードだけ書いておきます)


    余談ですが、このコメントを書いていて、
    「そういえば昔、とあるカフェのテーブルを借りて、初心者プログラミング講座をやった気がするなあ」
    と思い出して自分のGitHubを漁ったら、ありました。

    manzyun/NotTiteProgrammingSchool: プログラミングスクールの教科書というのか講師用ノート。英語にする予定は皆無。 https://github.com/manzyun/NotTiteProgrammingSchool

    拙作ですが、KyoheiさんのPythonプログラミング学習のお役に立てれば幸いです。

    キャンセル

  • 2018/11/02 16:08

    manzyun様 ご丁寧かつ大変分かりやすいご説明誠にありがとうございます!
    プログラミング講座受けてみたいです★
    ありがとうございます、先日githubアカウント取得したばかりなので拝読させていただきますね!
    いただいた説明は印刷して参考書に挟んでおきます!
    今後ともご指導ご鞭撻のほどお願い致します!

    キャンセル

+1

仮にmessageが'abaac'とすると

1文字目はa
count['a'] = 0
count['a'] = count['a'] + 1 (0 + 1 = 1)

2文字目はb
count['b'] = 0
count['b'] = count['b'] + 1 (0 + 1 = 1)

3文字目はa
count['a'] = count['a'] + 1 (1 + 1 = 2)

4文字目はa
count['a'] = count['a'] + 1 (2 + 1 = 3)

5文字目はc
count['c'] = 0
count['c'] = count['c'] + 1 (0 + 1 = 1)

結果、
count['a'] = 3
count['b'] = 1
count['c'] = 1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/24 14:04

    以下のように考えると分かりやすいかも。
    count.setdefault(character , 0)
    x=count[character]
    x=x+1
    count[character]=x

    キャンセル

  • 2018/11/02 13:07

    tabuu様
    ありがとうございます!

    キャンセル

0

count.setdefault(character,0) → countにcharacterがなければ「0」を返す。

count.setdefault(character,0)自身は常に0を返すわけではありません。また、コードを見れば分かる通り返り値は活用していません。

詳細な仕様はドキュメントなどで確認していただければ良いのですが、かいつまんでいえば

  • 第一引数のキーが存在しなければ新しくキーを作り、第二引数のデフォルト値を代入する。返り値はデフォルト値
  • 第一引数のキーが存在していれば辞書に対する変更はせず、キーの値を返す

という動作をしています。

count[character]=count[character]+1 →理解できず。。。

count[character]のカウントを+1しています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:06

    hayataka2049さま
    ありがとうございます!いつもご指導いただき感謝です!

    キャンセル

0

count[character]でその文字の出現回数が得られます。

'a'の文字が現れたとします。
aがまだ現れていない場合、

count.setdefault('a' , 0) # 'a': 0
count['a']=count['a'] + 1 # 1 = 0 + 1

aがすでに現れている場合、

# 4回目 'a': 3
count.setdefault('a' , 0) # 'a': 3 既に存在するので変化なし。
count['a']=count['a'] + 1 # 4 = 3 + 1


こんな感じの処理になっています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/02 13:05

    ysuzu6様
    ありがとうございます!
    大変助かります!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.58%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る