通过迭代给定数据返回字典列表

时间:2016-12-16 17:47:53

标签: python list python-3.x dictionary list-comprehension

所以,假设我有一份学生名单,并且有一本字典,其中包含每位学生的一些数据,如下所示:

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'}]

任何人都可以帮我识别代码中的问题吗?

5 个答案:

答案 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。