@MKsan (MK san)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

Pythonにおいて、変数名に変数を入れて、新しいリストを作る方法

python初心者です。for文で、入力した生徒数の各科目と点数を柔軟に設定できるような
コードをfor文の習熟練習のために作っています。以前、Pythonにおいて、変数名に変数を入れる方法についてにおいて質問した際は、連想配列を使った方が良いとコメントを受けて下記コードの1行目をリストに連想配列を組みあわせました。そして3行目で1行目で設定した科目を取り出すfor文を実行したのち、4行目で全生徒の科目ごとの点数を格納するリストの変数を作ろうとしたところで、変数の作成方法がわからず手が止まってしまいました。どのように変数を作ればいいのでしょうか。

kamoku = [{'kyoka':'国語'}, {'kyoka':'数学'}, {'kyoka':'社会'}, {'kyoka':'理科'}, {'kyoka':'英語'}]
students = int(input('生徒の人数を入力 >> '))
for i in range(len(kamoku)):
    ??? = list() #ここで手が止まった
    for j in range(students):
        score = int(input(f'{j + 1}人目の{kamoku[i]['kyoka']}の点数を入力 >> '))
        ???.append(score) #???は4行目で作成した変数

実現したいこと

以下のようなリストを作りたいと考えています(生徒の人数が3人、3人の点数が格納されたリストの場合)

国語_点数リスト = [34, 56, 45]
数学_点数リスト = [54, 100, 55]
社会_点数リスト = [67, 98, 43]
理科_点数リスト = [23, 67, 45]
英語_点数リスト = [89, 100, 77]
0 likes

5Answer

こんな実装はいかが?

scores = {'国語': [], '数学': [], '社会': [], '理科': [], '英語': []}
howmany = int(input('生徒の人数を入力 >> '))
for i in range(howmany):
    for subject in scores:
        score = int(input(f'{i + 1}人目の{subject}の点数を入力 >> '))
        scores[subject].append(score)

print(scores)
2Like

Comments

  1. ちなみに、グローバル変数に代入するとグローバル変数辞書に格納されます。
    辞書を変数として使ってます。

    >>> 国語_点数リスト = [34, 56, 45]
    >>> 数学_点数リスト = [54, 100, 55]
    >>> 社会_点数リスト = [67, 98, 43]
    >>> 理科_点数リスト = [23, 67, 45]
    >>> 英語_点数リスト = [89, 100, 77]
    >>> print(globals())  # グローバル変数辞書
    {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>,
     '国語_点数リスト': [34, 56, 45],
     '数学_点数リスト': [54, 100, 55],
     '社会_点数リスト': [67, 98, 43],
     '理科_点数リスト': [23, 67, 45],
     '英語_点数リスト': [89, 100, 77]}
    >>> type(globals())
    <class'dict'>
    >>> print(globals()['英語_点数リスト'])
    [89, 100, 77]
    

プログラミングには正解は無く、結果的にどのようなデータをどのように処理するか/したいか/残したいかによっても回答は違いますが、質問にある

Pythonにおいて、変数名に変数を入れる方法についてにおいて質問した際は、連想配列を使った方が良いとコメント

を、質問にあるコードにあてはめるのであれば、連想配列にすべきは、

kamoku = [{'kyoka':'国語'}, {'kyoka':'数学'}, {'kyoka':'社会'}, {'kyoka':'理科'}, {'kyoka':'英語'}]

ここではなく、

国語_点数リスト = [34, 56, 45]
数学_点数リスト = [54, 100, 55]
# 略

こっちです。
「xx_点数リスト」のxxを 国語・算数...のように入れ替えて新しい変数を作りたくなったときには、それは辞書(連想配列)の出番です。
ここはこのような辞書にします。(「国庫_点数リスト」というキー名でも構いません)

{
    "国語": [34, 56, 45],
    "数学": [54, 100, 55],
    # 略
 }

そして、これをscore_listのような変数にアサインするのがいいでしょう。

ただし、他の方も指摘しているように、このデータの持ちかたがいいかどうかは議論がわかれるところ。

質問のコードを生かして修正するなら こんな感じ

kamoku = ['国語', '数学', '社会', '理科', '英語']
students = int(input('生徒の人数を入力 >> '))
score_list = {}
for i in range(len(kamoku)):
    score_list[kamoku[i]] = list()
    for j in range(students):
        score = int(input(f'{j + 1}人目の{kamoku[i]}の点数を入力 >> '))
        score_list[kamoku[i]].append(score) 

print(score_list)

だた、自分で描くなら、

for i in range(len(kamoku)):

のところは

for kam in kamoku:

にしますけどね。

2Like

Pythonにおいて、変数名に変数を入れて、新しいリストを作る方法

”変数名を動的に作ろう”という考えを捨てた方が良いです。
実装についてはshiracamusさんの回答で良いかと思います。


自身でも実装してみました。

kamoku = {'国語':[], '数学':[], '社会':[], '理科':[], '英語':[]}
students = int(input('生徒の人数を入力 >> '))
for i in kamoku:
    for j in range(students):
        score = int(input(f'{j + 1}人目の{i}の点数を入力 >> '))
        kamoku[i].append(score)
        
for i in kamoku:
    print(f'{i}: {kamoku[i]}')
1Like

4行目で全生徒の科目ごとの点数を格納するリストの変数を作ろうとしたところで、変数の作成方法がわからず

変数の作成方法というよりロジックの組み立て方に問題があります。

4行目の??? = list()が手前のforでループする度に初期化されていることに気づいていますか?
結果的に最後に入力した生徒のリストしか代入されてないはずです。

ループする度に初期化されるのですから、forの外で初期化をしたら良いのです。

1Like

Comments

  1. 「変数名に変数を入れて、新しいリストを作る方法」を知りたがっているので???にはループ毎に新たな変数(名)が生成されることになっているのだと思います。通常やらない方法だとは思いますが。

  2. それは理解してます。

    リスト構造を質問者自身が考えて組み立てないと、単純に答えだけ与えても理解出来てなければ意味はありません。
    とりあえず??? = list()が初期化される謎は解かせる必要はあります。

    (そういう意味で「ロジックの組み立て」に問題があると答えています)

元の実装をそのまま使うならこうですかね?

kamoku = [{'kyoka':'国語'}, {'kyoka':'数学'}, {'kyoka':'社会'}, {'kyoka':'理科'}, {'kyoka':'英語'}]
students = int(input('生徒の人数を入力 >> '))
for i in range(len(kamoku)):
    kamoku[i]['scores'] = list()
    for j in range(students):
        score = int(input(f'{j + 1}人目の{kamoku[i]['kyoka']}の点数を入力 >> '))
        kamoku[i]['scores'].append(score)
for k in kamoku:
    print(f'{k['kyoka']}_点数リスト = {k['scores']}')

ただ、点数はどちらかというとstudentに格納した方がそれっぽいと思うので、こんな感じの方がいいんじゃないかと。

kamoku = ['国語', '数学', '社会', '理科', '英語']
students = [dict()] * int(input('生徒の人数を入力 >> '))
for i in range(len(students)):
    students[i]['scores'] = list()
    students[i]['name'] = input(f'{i + 1}人目の名前を入力 >> ')
for kamoku_name in kamoku:
    for student in students:
        message = f'{student['name']}さんの{kamoku_name}の点数を入力 >> '
        student['scores'].append(int(input(message)))
def kamoku_scores(kamoku_index):
    scores = []
    for student in students:
        scores.append(student['scores'][kamoku_index])
    return scores
for i in range(len(kamoku)):
    print(f'{kamoku[i]}_点数リスト = {kamoku_scores(i)}')
0Like

Comments

  1. @MKsan

    Questioner

    みなさま、ありがとうございます!
    (所要あって回答が遅れたこと申し訳ないです)

    scoresを辞書として、Keyを科目、値には空のリストを埋め込んで、その中に生徒ごとの点数を追加する方法は思いつかなかったです。勉強になりました。また「変数名を動的に作る」という思想がそもそも良くないと理解しました。今後、変数を定義する上で意識いたします。

    リスト構造を自身が考えて組み立てないといけないというのは、Pythonに限らず、どの言語でも共通するところであると思います、私自身その能力が足りてないというのは理解しており、日々勉強中です・・・みなさまの回答やインターネットで調べる等して、能力を高められるよう努めております

Your answer might help someone💌