@MKsan (MK san)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Pythonにおいて、変数名に変数を入れる方法について

python初心者です。点数計算コードを使って、引数と戻り値の勉強をしており、呼び出しの部分でfor文を使ってコードを見やすくしたいと考えています。表題の通り変数名に変数を入れようとしたところ、エラーが出て解決方法がわからないため、ご教授いただけると幸いです

点数計算コード

とある参考書に記載された、生徒の得点科目の平均値を求めるコードは以下のようになっていました。

def input_scores(name):
    scores = list()
    scores.append(int(input(f'{name}さんの国語の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの数学の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの社会の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの理科の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの英語の点数を入力>> ')))
    return scores

def calc_avg(totalscore):
    avg = sum(totalscore)/len(totalscore)
    return avg

def result(resultName, resultAvg):
    print(f'{resultName}さんの平均点は{resultAvg}点です')

kawata_scores = input_scores('川田')
kawata_avg = calc_avg(kawata_scores)
kawata_result = result('川田', kawata_avg)

oono_scores = input_scores('大野')
oono_avg = calc_avg(oono_scores)
oono_result = result('大野', oono_avg)

呼び出し箇所のコードについて、生徒の数が増えるほど同じコードを書く必要があり冗長的となってコードの可読性が低下すると思いました。そのため呼び出し箇所のコードについてfor文を使ったほうがスッキリすると思い、以下のコードに修正しようとしたところ、studentList = ['山田', '大野', '佐藤']以降の変数名の変数numを入れる方法がわからず、手詰まりとなってしまいました。解消方法を教えていただけますでしょうか

点数計算コード(呼び出し箇所にfor文を使用)

def input_scores(name):
    scores = list()
    scores.append(int(input(f'{name}さんの国語の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの数学の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの社会の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの理科の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの英語の点数を入力>> ')))
    return scores

def calc_avg(totalscore):
    avg = sum(totalscore)/len(totalscore)
    return avg

def result(resultName, resultAvg):
    print(f'{resultName}さんの平均点は{resultAvg}点です')

studentList = ['山田', '大野', '佐藤']
for num in range(len(studentList)):
    studentList[num] + _score = input_scores(studentList[num]) #ここでつまづいた
    studentList[num] + _avg = calc_avg(studentList[num].score)
    studentList[num] + _result = result(studentList[num], studentList[num].avg )

自分で試したこと

studentList[num] + _score = input_scores(studentList[num]) とした場合

SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?

が出ました。エラー内容から

studentList[num] + _score == input_scores(studentList[num])

に修正したところ、「_score」のところが定義されていませんというエラーが出ました。

0 likes

3Answer

studentList[num] + _score = input_scores(studentList[num])

配列にこのような方法で値を追加することはできません
連想配列を使いましょう


def input_scores(name):
    scores = list()
    scores.append(int(input(f'{name}さんの国語の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの数学の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの社会の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの理科の点数を入力>> ')))
    scores.append(int(input(f'{name}さんの英語の点数を入力>> ')))
    return scores

def calc_avg(totalscore):
    avg = sum(totalscore)/len(totalscore)
    return avg

def result(resultName, resultAvg):
    print(f'{resultName}さんの平均点は{resultAvg}点です')


studentList = [{"name":'山田'}, {"name": '大野'}, {"name": '佐藤'}]

for num in range(len(studentList)):
    studentList[num]["score"] = input_scores(studentList[num]["name"])#ここでつまづいた
    studentList[num]["avg"] = calc_avg(studentList[num]["score"])
    studentList[num]["result"] = result(studentList[num]["name"], studentList[num]["avg"] )

1Like

Comments

  1. @MKsan

    Questioner

    amateさん、コメントありがとうございます!
    連想配列という、リストと辞書を組み合わせたものがあるんですね。勉強になりました。またamateさん修正したコードの通りにデバックしたところ、所望の動作となりました。

    input_scores(studentList[num]["name"])というコードから、実引数にキー(name)を入れることで、num番目のキーの値が参照されると理解しましたがあってますでしょうか?

  2. studentListのnum番目のキーの値は連想配列です
    連想配列に"name"を与えることで対応する値(山田や大野)が取り出せます

    name = studentList[num]["name"]
    

    という書き方は

    student = studentList[num]
    name = student["name"]
    

    上記を省略して書いているだけです

  3. @MKsan

    Questioner

    コメントありがとうございます!より理解が深まりました。

    解決したのでクローズとします

  4. @MKsan

    連想配列という、リストと辞書を組み合わせたものがあるんですね。

    連想配列とは辞書のことです。Python でいう辞書を他の言語では連想配列と呼ぶことがあります。(他には MapHash とも)

This answer has been deleted for violation of our Terms of Service.

クラス(役、係、担当)にする手もありますよ。

# 処理中に変更しない定数 (変数名を大文字にする)
NAMES = '山田', '大野', '佐藤'
SUBJECTS = '国語', '数学', '社会', '理科', '英語'


class Student:
    """成績を管理・処理する生徒役(生徒に関する責務を担う)"""

    def __init__(self, name: str) -> None:
        """名前nameの生徒役を作成"""
        self.name = name

    def input_scores(self) -> None:
        """全科目(SUBJECTS)の点数を入力してself.scoresに格納"""
        self.scores: dict[str, int] = {}  # 科目名と点数の辞書
        for subject in SUBJECTS:
            self.scores[subject] = int(input(f'{self.name}さんの{subject}の点数を入力>> '))

    def score(self, subject: str) -> int:
        """科目subjectの点数を返す"""
        return self.scores[subject]

    def average(self) -> float:
        """全科目の平均点を返す"""
        return sum(self.scores.values()) / len(self.scores)


def average(students: list[Student], subject: str) -> float:
    """全生徒studentsの科目subjectの平均点を返す"""
    score = 0
    for student in students:
        score += student.score(subject)
    return score / len(students)


students: list[Student] = []
for name in NAMES:
    student = Student(name)
    student.input_scores()
    students.append(student)
    # 生徒の平均点を表示
    print(f'{student.name}さんの平均点は{student.average()}点です')

# 科目毎の平均点を表示
for subject in SUBJECTS:
    print(f'{subject}の平均点は{average(students, subject)}点です')
0Like

Your answer might help someone💌