2017-09-18 3 views
2

入れ子になっている辞書では割り当てが難しいです。私は2つの学校、3人の教師、そして4人の学生を入れ子にした辞書を持っています。これは単なるおもちゃの例なので、私は学生と教師が各学校で同じであることに気をつけません。しかし、私はそれぞれの成績が異なることを望んでいます。ただし、以下のコードでは、すべてのクラスとすべての学校のすべての生徒の成績は、最後に入力した学校/クラスと同じです。入れ子の辞書の割り当てエラー - 変更可能な辞書の混乱

schools = ['School A', 'School B'] 
teachers = ['mr. smith', 'ms. jones', 'mr. kronk'] 
students = ['Adam', 'Nick', 'Jeff', 'Dave'] 
grade_dict ={} 
for i in students: 
    grade_dict[i] = '' 
    for j in teachers: 
     teachers_dict[j] = grade_dict 
     for k in schools: 
      school_dict[k] = teachers_dict 
for k in schools: 
    for j in teachers: 
     for i in students: 
      a = [randint(70, 100), randint(70, 100), randint(70, 100)] 
      school_dict[k][j][i] = a 

これは、私は、データが見えるようにしたいものです。

School A mr. smith Adam [71, 72, 82] 
School A mr. smith Nick [86, 80, 96] 
School A mr. smith Jeff [77, 70, 83] 
School A mr. smith Dave [79, 83, 98] 
School A ms. jones Adam [70, 98, 87] 
School A ms. jones Nick [80, 94, 76] 
School A ms. jones Jeff [79, 82, 93] 
School A ms. jones Dave [90, 97, 85] 
School A mr. kronk Adam [93, 75, 95] 
School A mr. kronk Nick [80, 82, 72] 
School A mr. kronk Jeff [75, 72, 89] 
School A mr. kronk Dave [86, 92, 98] 
School B mr. smith Adam [89, 77, 84] 
School B mr. smith Nick [93, 71, 74] 
School B mr. smith Jeff [78, 83, 83] 
School B mr. smith Dave [72, 83, 70] 
School B ms. jones Adam [82, 100, 78] 
School B ms. jones Nick [80, 89, 100] 
School B ms. jones Jeff [91, 81, 77] 
School B ms. jones Dave [86, 86, 74] 
School B mr. kronk Adam [82, 73, 100] 
School B mr. kronk Nick [81, 71, 74] 
School B mr. kronk Jeff [92, 100, 90] 
School B mr. kronk Dave [86, 97, 85] 

これは、残念ながら、対応する辞書は次のようになります。

{'School A': {'mr. kronk': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}, 
    'mr. smith': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}, 
    'ms. jones': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}}, 
'School B': {'mr. kronk': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}, 
    'mr. smith': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}, 
    'ms. jones': {'Adam': [86, 89, 94], 
    'Dave': [74, 85, 86], 
    'Jeff': [79, 94, 70], 
    'Nick': [90, 80, 97]}}} 

同様の質問があるように見えます私はここで何が起こっていたのかを解決することはできませんでした。ありがとう。

答えて

1

あなたは辞書内包表記を使用することができます。

from random import randint 
schools = ['School A', 'School B'] 
teachers = ['mr. smith', 'ms. jones', 'mr. kronk'] 
students = ['Adam', 'Nick', 'Jeff', 'Dave'] 

final_dict = {school:{teacher:{student:[randint(70, 100), randint(70, 100), randint(70, 100)] for student in students} for teacher in teachers} for school in schools} 

出力:

{'School A': {'mr. smith': {'Nick': [75, 81, 86], 'Dave': [85, 88, 84], 'Adam': [78, 95, 99], 'Jeff': [74, 95, 81]}, 'ms. jones': {'Nick': [76, 86, 92], 'Dave': [92, 100, 95], 'Adam': [98, 99, 90], 'Jeff': [74, 100, 95]}, 'mr. kronk': {'Nick': [84, 97, 79], 'Dave': [93, 91, 89], 'Adam': [83, 98, 79], 'Jeff': [89, 83, 99]}}, 'School B': {'mr. smith': {'Nick': [70, 78, 89], 'Dave': [81, 95, 92], 'Adam': [95, 100, 91], 'Jeff': [91, 83, 82]}, 'ms. jones': {'Nick': [94, 85, 75], 'Dave': [99, 77, 94], 'Adam': [79, 97, 92], 'Jeff': [91, 84, 79]}, 'mr. kronk': {'Nick': [81, 90, 86], 'Dave': [72, 95, 82], 'Adam': [80, 73, 77], 'Jeff': [88, 88, 95]}}} 
+0

ハードそうのような最後のdictのが最善ではないコーディング。 –

+0

これは辞書を初期化するクールな方法です(ありがとう!)が、ネストされた辞書の最も低いレベルで一意の値を作成するという問題を解決することはできません。 –

+0

@GeoffPerrin私はあなたが学生のスコアを無作為化したかったと気付かなかったことをお詫びします!私の最近の編集を見てください。 – Ajax1234

1

dict全体で同じgrade_dictオブジェクトを(再)使用しています。 反復ごとに個別のオブジェクトを作成します。また、あなたは、各キーに値を初期化する必要はありません。

for i in students: 
    for j in teachers: 
     teachers_dict[j] = {} 
     for k in schools: 
      school_dict[k] = teachers_dict 

OTOH、ネストされたcollections.defaultdictを使用してschool_dictを宣言することによってためと値/ dictsを事前に割り当てることは避けてください。

from collections import defaultdict 

school_dict = defaultdict(lambda: school_dict) # dict nesting is recursive 

for k in schools: 
    for j in teachers: 
     for i in students: 
      school_dict[k][j][i] = [randint(70, 100), randint(70, 100), randint(70, 100)] 
関連する問題