首页 > 解决方案 > 如何根据两个值对字典进行分组?

问题描述

如何根据多个关键元素将字典列表分组为唯一字典列表?

in = [{'location': 'eastus', 'sku': 'S', 'term': 'P1', 'scope': '1'},
         {'location': 'india', 'sku': 'a', 'term': 'P1', 'scope': '2'},
         {'location': 'eastus', 'sku': 'S', 'term': 'P3', 'scope': '3'},
         {'location': 'india', 'sku': 'f', 'term': 'P1', 'scope': '4'},
         {'location': 'japan', 'sku': 'a', 'term': 'P1', 'scope': '5'},
         {'location': 'india', 'sku': 'a', 'term': 'P3', 'scope': '6'}
      ]

关键元素是“位置”和“sku”。我想将具有相同键元素的字典分组到一个字典中,其中具有不同值的其余键将进入同一字典内的单独字典列表中。

预期输出:

out = [{'location': 'eastus', 'sku': 'S', 'new_key': [
                                                     {'term': 'P1', 'scope': '1'}, 
                                                     {'term': 'P3', 'scope': '3'}
                                                    ]},
           {'location': 'india', 'sku': 'a', 'new_key': [
                                                     {'term': 'P1', 'scope': '2'},
                                                     {'term': 'P3', 'scope': '6'}
                                                    ]},
           {'location': 'india', 'sku': 'f', 'term': 'P1', 'scope': '4'},
           {'location': 'japan', 'sku': 'a', 'term': 'P1', 'scope': '5'},
        ]

我已经尝试过进行必要的修改,但我们有更好、更准确的解决方案吗?

标签: pythonlistdictionarygroup-by

解决方案


使用itertools.groupby

前任:

from itertools import groupby

data = [{'location': 'eastus', 'sku': 'S', 'term': 'P1', 'scope': '1'},
         {'location': 'india', 'sku': 'a', 'term': 'P1', 'scope': '2'},
         {'location': 'eastus', 'sku': 'S', 'term': 'P3', 'scope': '3'},
         {'location': 'india', 'sku': 'f', 'term': 'P1', 'scope': '4'},
         {'location': 'japan', 'sku': 'a', 'term': 'P1', 'scope': '5'},
         {'location': 'india', 'sku': 'a', 'term': 'P3', 'scope': '6'}
      ]
result = []
for k, v in groupby(sorted(data, key=lambda x: (x["location"], x["sku"])), lambda x: (x["location"], x["sku"])):
    temp = dict(zip(('location', 'sku'), k))
    sub_value = list(v)
    if len(sub_value) == 1:
        temp.update(sub_value[0])
    else:
        temp.update({'new_key': sub_value})
    result.append(temp)

print(result)

输出:

[{'location': 'eastus',
  'new_key': [{'location': 'eastus', 'scope': '1', 'sku': 'S', 'term': 'P1'},
              {'location': 'eastus', 'scope': '3', 'sku': 'S', 'term': 'P3'}],
  'sku': 'S'},
 {'location': 'india',
  'new_key': [{'location': 'india', 'scope': '2', 'sku': 'a', 'term': 'P1'},
              {'location': 'india', 'scope': '6', 'sku': 'a', 'term': 'P3'}],
  'sku': 'a'},
 {'location': 'india', 'scope': '4', 'sku': 'f', 'term': 'P1'},
 {'location': 'japan', 'scope': '5', 'sku': 'a', 'term': 'P1'}]

推荐阅读