【问题标题】:Returning a list of dictionaries by iterating over given data通过迭代给定数据返回字典列表
【发布时间】:2023-03-03 10:29:01
【问题描述】:

假设我有一个学生列表,并且有一个包含每个学生的一些数据的字典,如下所示:

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)

我希望在输出中,对于每个 student ,会有一个字典,其键为 'name',值是从 'students' 列表中获取的学生姓名。我希望它如下所示:

[{'name': 'name1'}, {'name': 'name2'}, {'name': 'name3'}]

但是输出结果是这样的:

[{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}]

谁能帮我找出我的代码中的问题?

【问题讨论】:

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


    【解决方案1】:

    list的微妙概念是它不会复制你附加到它的项目。相反它只是通过附加存储指向新添加的对象的指针,类似于c中的指针数组。所以当你尝试@ 987654321@,它会给你这样的结果[{'name': 'name3'}, {'name': 'name3'}, {'name': 'name3'}]。但是当你将它附加到列表中时,列表中的所有项目都指向同一个对象。你可以通过这段代码来验证这一点

    for i in res_list:
        print(id(i))
    

    您会发现所有列表元素的内存地址相同。 但是,当您在 d.copy() 的帮助下获取字典的副本并将其附加到 res_list 时,您可以看到所有列表对象都通过使用 id(i) 和 for 循环的相同技术指向不同的对象如上图所示。 所以最后更正的代码是

    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.copy())
    
    print(res_list)
    

    使用列表推导总是会暴露要修改的内容。

    【讨论】:

      【解决方案2】:

      获得所需结果的更好方法是使用 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']})
      

      【讨论】:

      • @CodePlorer:但是你刚才提到的部分在 OP 中没有提到。我想您应该能够修改我提到的嵌套字典中多个键的示例。如果有其他问题,请创建新问题
      • 但是如果只有一个键,这很好用,我希望它返回一个列表,其中每个学生都有一个字典,每个学生都有多个键值对: res_list.append({'name': student['student_name']}) res_list.append({'register':student['regNO']}) 返回如下内容: [{'name': 'name1'}, {'register': '12'} , {'name': 'name2'}, {'register': '13'}, {'name': 'name3'}, {'register': '14'}] 虽然我希望输出如下:[ {'name': 'name1', 'register': '12'}, {'name': 'name2', 'register': '13'}, {'name': 'name3', 'register': ' 14'}]
      • @CodePlorer 用{'name': student['student_name'], 'register': student['regNO']}更新我的代码sn-p中的dict
      【解决方案3】:

      对于每个新条目,您应该在循环中将 res_dict = {} 重置为一个空字典。

      【讨论】:

        【解决方案4】:

        这是一个简单的方法。

        n_list = [{'name':i['student_name']} for i in students]
        

        【讨论】:

          【解决方案5】:

          这是一个经典的参考问题。换句话说,您将引用附加到同一个 dict 对象。因此,当您更改其名称值时,它始终显示在列表中,它将反映其新值。相反,为每次迭代创建一个新的 dict 并附加它:)

          【讨论】:

            猜你喜欢
            • 2017-03-25
            • 1970-01-01
            • 1970-01-01
            • 2016-10-27
            • 1970-01-01
            • 1970-01-01
            • 2022-08-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多