我正在尝试使用列表列表中的字典理解来创建字典字典。
列表列表包含学生姓名,作业名称和成绩。例如,数据可能如下所示:
grades_lists = [
['Student', 'Test', 'Assignment', 'Exam'],
['Bella', '80', '90', '100'],
['Sam', '65', '75', '85'],
['Emily', '60', '75', '90'],
]
我想创建一个字典,将学生姓名映射到包含作业名称和成绩的字典。例如:
grades_dicts['Bella']['Test'] == 80
我想要的字典是:
{
'Bella': {'Test': 80, 'Assignment': 90, 'Exam': 100},
'Sam': {'Test': 65, 'Assignment': 75, 'Exam': 85},
'Emily': {'Test': 60, 'Assignment': 75, 'Exam': 90}
}
因此grades_list
中的每一行都成为字典;第一列是学生的名字,其他列是字典中的值,其中的键取自grades_list
的第一行。
我一直在尝试使用dict理解来生成字典中的相应键和值。像这样:
grade_dicts = {x[0]:{y:z} for y in grades_lists[0][1:] for x in grades_lists[1:] for z in x[1:]}
但这并没有正确生成所有成绩:
{
'Bella': {'Exam': '100'},
'Emily': {'Exam': '90'},
'Sam': {'Exam': '85'}
}
答案 0 :(得分:4)
你的巢穴混乱了。以下作品:
{name: {col: int(value) for col, value in zip(grades_list[0][1:], row)}
for name, *row in grades_list[1:]}
for name, *row in ...
循环占用每一行,只将第一个值提取到name
,余数提取到row
(*
告诉Python取余数)。这使您可以将该行与第一行中的列名一起使用来创建嵌套字典。
通过使用常规循环,通常更容易看到理解的作用。您的代码执行此操作:
grade_dicts = {}
for y in grades_lists[0][1:]:
for x in grades_lists[1:]:
for z in x[1:]:
grade_dicts[x[0]] = {y:z}
那种循环太多了,你最终会为x[0]
多次设置一个值;事实上len(x[1:])
次。只剩下最后一个{y: z}
字典。
我的版本执行此操作:
grade_dicts = {}
for name, *row in grades_list[1:]:
inner = {}
for col, value in zip(grades_list[0][1:], row):
inner[col] = int(value)
grade_dicts[name] = inner
这只是两个循环,其中内部为每列产生一个单独的字典。我使用zip()
配对标签和值。