首页 > 解决方案 > 将 Python 字典列表转换为按键分组的字典排序列表

问题描述

我需要帮助在 Python 中按键对字典列表进行分组。我有听写列表:

raw_values = [
              {'qty': 1, 'price': 11.0, 'name': 'Name 1', 'id': '111'},
              {'qty': 2, 'price': 22.0, 'name': 'Name 2', 'id': '111'},
              {'qty': 3, 'price': 33.0, 'name': 'Name 3', 'id': '111'},
              {'qty': 0, 'price': 12.0, 'name': 'Name 1', 'id': '222'},
              {'qty': 3, 'price': 13.0, 'name': 'Name 2', 'id': '222'},
              {'qty': 7, 'price': 14.0, 'name': 'Name 2', 'id': '333'},
              {'qty': 10, 'price': 15.0, 'name': 'Name 3', 'id': '333'}]

基于该列表,我需要创建一个新的字典列表,我可以在其中按“id”键对记录进行分组,还可以正确重命名和填充其他列 - 名称和数量(如果不是某些“id”的任何记录,我需要将它们留空)。期望的输出:

sorted_values = [
                {"id": "111",
                 "name_1_price": 11.0, "name_1_qty": 1,
                 "name_2_price": 22.0, "name_2_qty": 2,
                 "name_3_price": 33.0, "name_3_qty": 3},
                {"id": "222",
                 "name_1_price": 12.0, "name_1_qty": 0,
                 "name_2_price": 13.0, "name_2_qty": 3,
                 "name_3_price": None, "name_3_qty": None
                 },
                {"id": "333",
                 "name_1_price": None, "name_1_qty": None,
                 "name_2_price": 14, "name_2_qty": 7,
                 "name_3_price": 15.0, "name_3_qty": 10
                 }
               ]

我试图寻找解决方案,我认为我需要使用itertools.groupby函数按“id”键进行分组。但我不知道 - 我如何按 'id' 分组并根据 'name' 中的值重命名和填充字典?

标签: pythondictionary

解决方案


熊猫解决方案:

import pandas as pd

raw_values = [
              {'qty': 1, 'price': 11.0, 'name': 'Name 1', 'id': '111'},
              {'qty': 2, 'price': 22.0, 'name': 'Name 2', 'id': '111'},
              {'qty': 3, 'price': 33.0, 'name': 'Name 3', 'id': '111'},
              {'qty': 0, 'price': 12.0, 'name': 'Name 1', 'id': '222'},
              {'qty': 3, 'price': 13.0, 'name': 'Name 2', 'id': '222'},
              {'qty': 7, 'price': 14.0, 'name': 'Name 2', 'id': '333'},
              {'qty': 10, 'price': 15.0, 'name': 'Name 3', 'id': '333'}]

#create DataFrame from dictionary
df = pd.DataFrame(raw_values)
print (df)
    id    name  price  qty
0  111  Name 1   11.0    1
1  111  Name 2   22.0    2
2  111  Name 3   33.0    3
3  222  Name 1   12.0    0
4  222  Name 2   13.0    3
5  333  Name 2   14.0    7
6  333  Name 3   15.0   10

#change value to lower and replace empty spaces
df['name'] = df['name'].str.lower().str.replace('\s+','_')
#reshape by unstack, sorting
df = df.set_index(['id','name']).unstack().sort_index(level=1, axis=1).swaplevel(1,0,axis=1)
#flatten MultiIndex 
df.columns = df.columns.map('_'.join)
df = df.reset_index()
#convert NaN to None
df = df.mask(df.isnull(), None)

#convert to list of dicts
L = df.to_dict(orient='records')
print (L)
[{'id': '111', 
  'name_1_price': 11.0, 'name_1_qty': 1.0, 
  'name_2_price': 22.0, 'name_2_qty': 2.0, 
  'name_3_price': 33.0, 'name_3_qty': 3.0}, 
 {'id': '222', 
  'name_1_price': 12.0, 'name_1_qty': 0.0, 
  'name_2_price': 13.0, 'name_2_qty': 3.0, 
  'name_3_price': None, 'name_3_qty': None}, 
 {'id': '333', 
  'name_1_price': None, 'name_1_qty': None, 
  'name_2_price': 14.0, 'name_2_qty': 7.0, 
  'name_3_price': 15.0, 'name_3_qty': 10.0}]

推荐阅读