28028


Pythonで下記関数を作ると、次のようなエラーが発生しました。

[code]

    alice = {
    "name": "Alice", 
    "homework": [100.0, 92.0, 98.0, 100.0],
    "quizzes": [82.0, 83.0, 91.0],
    }
    
    def average(numbers):
        total = float(sum(numbers))
        total = total / len(numbers)
        return total
    
    def get_average(student):
        homework = average(student["homework"])
        quizzes = average(student["quizzes"])
        total = float(0.5*homework + 0.5*quizzes)
        return total
    
    student = alice #test alice
    print(get_average(alice))  #correctly works
    
    def get_class_average(students):
        results = []
        for student in students:
            results.append(get_average(student))
        return average(results)
    
    students = alice #test alice
    print(get_class_average(students)) #error 
    
[/code]

> Traceback (most recent call last):  
>  File "", line 28, in  
>  File "", line 24, in get_class_average  
>  File "", line 13, in get_average  
>  TypeError: string indices must be integers

27行目の`alice`を、`[alice]`に変更したらうまく動作するようになりました。

双方を[PythonTutor](http://www.pythontutor.com/live.html) で比較確認したところ、Step
27においてリストが作られるかどうかが違っており、また`alice`の方ではStep
31のfor文実行時に、`get_class_average`の`student`に辞書の文字列キーがひとつ入ってしまっていました。

そこで質問なのですが、どうして19行目では`get_average`が`alice`で動作したのに、28行目の`get_class_average`から呼び出した`get_average`において`alice`では文字列が入ってしまい、うまく動かないのでしょうか。for文に関係していると思うのですが、よくわかりません。


CC BY-SA 3.0
2016-08-02T11:21:36.343
28023
2016-08-03T10:21:28.930
2016-08-02T16:58:06.570
76
17364
question
python
for文と辞書・リストについての質問


get_class_averageがaliceと同じようなキーを持つ辞書型の配列を引数に持つことを想定しているから。


CC BY-SA 3.0
2016-08-02T12:29:49.163
28024
2016-08-02T12:29:49.163
7232
28023
answer


以下のコードはPython3.3でチェックしています。

次のコードを実行して見れば分かりますが、辞書に対する`for`は辞書のキーの反復になります。

[code]

    alice = {
    "name": "Alice", 
    "homework": [100.0, 92.0, 98.0, 100.0],
    "quizzes": [82.0, 83.0, 91.0],
    }
    for elem in alice:
      print(elem)
    
[/code]

従って`get_class_average`の中では文字列に対して`get_average`を呼んでいることになります。さらに`get_average`の中では引数に対して文字列のインデックスを与えています。今回の場合は文字列に対してそのようなインデックスを与えることになるため型エラーが出ています。

[code]

    "mojiretsu"["idx"]
    
[/code]

->`TypeError: string indices must be integers`

また、`get_class_average`はalice,bob,...のような複数の生徒に対して平均を求めるという意図で書かれている（と思う）ので、`alice`をそのまま`get_class_average`に渡すのではなく、`alice`一人しかいない教室であると考えて`[alice]`としてやるのが正しい関数の使い方でしょう。


CC BY-SA 3.0
2016-08-02T14:12:06.113
28028
2016-08-03T10:21:28.930
2016-08-03T10:21:28.930
13199
13199
28023
answer