所以,假设我有一份学生名单,并且有一本字典,其中包含每位学生的一些数据,如下所示:
students= [{'student_name': 'name1',
'regNO': '12',
},{'student_name': 'name2',
'regNO': '13',
},{'student_name': 'name3',
'regNO': '14',
}
]
因此,基于上述数据,我想返回另一个包含每个学生数据的词典列表,
我写了以下代码:
res_dict = {}
res_list = []
for student in students:
res_dict['name']=student['student_name']
res_list.append(res_dict)
print(res_list)
我希望在输出中,对于每个学生,会有一个字典,其中键是“姓名”,而值是从“学生”列表中取得的学生姓名。我预计它会如下:
[{'name': 'name1'}, {'name': 'name2'}, {'name': 'name3'}]
但输出结果是这样的:
[{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}]
任何人都可以帮我识别代码中的问题吗?
答案 0 :(得分:4)
获得所需结果的更好方法是使用 list comprehension 表达式:
[{'name': student['student_name']} for student in students]
您的代码的问题是您正在更新dict
对象的相同引用中的值,并将同一对象再次附加到列表中。将您的代码更改为:
for student in students:
res_dict = {} # Create new `dict` object
res_dict['name'] = student['student_name']
res_list.append(res_dict)
或者,您可以这样做:
for student in students:
res_list.append({'name': student['student_name']})
答案 1 :(得分:1)
list的微妙概念是它不会复制你附加到它的项目。而不是它只是通过append将指针存储到新添加的对象,类似于c.So中的指针数组,当你尝试{ {1}},它将为您提供类似print(res_dict)
的结果。但是当您将此附加到列表中时,列表中的所有项目都指向同一个对象。您可以通过这个小片段来验证这一点。代码
[{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}]
您将找到所有列表元素的相同内存地址。 但是当您在d.copy()的帮助下获取字典的副本并将其附加到res_list时,您可以看到所有列表对象都使用id(i)和for循环通过相同的技术指向不同的对象如上所示。 所以最后纠正的代码将是
for i in res_list:
print(id(i))
使用列表推导将始终公开要修改的内容。
答案 2 :(得分:0)
这是一个经典的参考问题。换句话说,您将引用添加到同一个dict对象。因此,当您更改其上的名称值时,它在列表中显示的所有时间都将反映其新值。相反,为每次迭代创建一个新的dict并附加:)
答案 3 :(得分:0)
这是一种简单的方法。
n_list = [{'name':i['student_name']} for i in students]
答案 4 :(得分:0)
对于每个新条目,您应该将res_dict = {}
重置为循环中的空dict。