按特定键对列表中的字典项进行分组
Group dictionary items in a list by their specific keys
我有这个示例列表:
my_list = [
{
'data': {
'color': 'white'
},
'name': 'item1'
},
{
'data': {
'color': 'white',
'property': 'value1'
},
'name': 'item2'
},
{
'data': {
'color': 'white',
'property': 'value1'
},
'name': 'item3'
},
{
'data': {
'color': 'black',
'property': 'value1'
},
'name': 'item4'
},
{
'data': {
'color': 'white',
'property': 'value1',
'custom': 'valueA'
},
'name': 'item5'
},
{
'data': {
'color': 'white'
},
'name': 'item6'
},
]
我想将字典项目的名称值与共享相同 'data' 值的项目的其他名称值分组。
所以我想为这个特定的例子得到这个结果:
result = [('item1', 'item6'), ('item2', 'item3')]
根据要求更新:
我尝试使用 groupby 将它们分开但没有成功:
import itertools
for key, group in itertools.groupby([item["data"] for item in my_list]):
print("-"*10)
for data in group:
print(data)
out = {}
for d in my_list:
out.setdefault(tuple(d['data'].items()), []).append(d['name'])
out = [v for v in out.values() if len(v) > 1]
print(out)
打印:
[['item1', 'item6'], ['item2', 'item3']]
您可以使用itertools.groupby
from itertools import groupby
keyfunc = lambda x: sorted(zip(x['data'].keys(), x['data'].values()))
ls = sorted(my_list, key = keyfunc)
groups = []
for k, g in groupby(ls, keyfunc):
groups.append([n['name'] for n in g])
>>> groups
[['item4'], ['item1', 'item6'], ['item5'], ['item2', 'item3']]
样本运行:
>>> sorted(map(keyfunc, my_list))
[[('color', 'black'), ('property', 'value1')],
[('color', 'white')],
[('color', 'white')],
[('color', 'white'), ('custom', 'valueA'), ('property', 'value1')],
[('color', 'white'), ('property', 'value1')],
[('color', 'white'), ('property', 'value1')]]
>>> ls
[{'data': {'color': 'black', 'property': 'value1'}, 'name': 'item4'},
{'data': {'color': 'white'}, 'name': 'item1'},
{'data': {'color': 'white'}, 'name': 'item6'},
{'data': {'color': 'white', 'property': 'value1', 'custom': 'valueA'}, 'name': 'item5'},
{'data': {'color': 'white', 'property': 'value1'}, 'name': 'item2'},
{'data': {'color': 'white', 'property': 'value1'}, 'name': 'item3'}]
备注:itertools.groupby
中的组只允许包含一个项目。你可以用:
>>> [n for n in groups if len(n) > 1]
[['item1', 'item6'], ['item2', 'item3']]
我有这个示例列表:
my_list = [
{
'data': {
'color': 'white'
},
'name': 'item1'
},
{
'data': {
'color': 'white',
'property': 'value1'
},
'name': 'item2'
},
{
'data': {
'color': 'white',
'property': 'value1'
},
'name': 'item3'
},
{
'data': {
'color': 'black',
'property': 'value1'
},
'name': 'item4'
},
{
'data': {
'color': 'white',
'property': 'value1',
'custom': 'valueA'
},
'name': 'item5'
},
{
'data': {
'color': 'white'
},
'name': 'item6'
},
]
我想将字典项目的名称值与共享相同 'data' 值的项目的其他名称值分组。
所以我想为这个特定的例子得到这个结果:
result = [('item1', 'item6'), ('item2', 'item3')]
根据要求更新: 我尝试使用 groupby 将它们分开但没有成功:
import itertools
for key, group in itertools.groupby([item["data"] for item in my_list]):
print("-"*10)
for data in group:
print(data)
out = {}
for d in my_list:
out.setdefault(tuple(d['data'].items()), []).append(d['name'])
out = [v for v in out.values() if len(v) > 1]
print(out)
打印:
[['item1', 'item6'], ['item2', 'item3']]
您可以使用itertools.groupby
from itertools import groupby
keyfunc = lambda x: sorted(zip(x['data'].keys(), x['data'].values()))
ls = sorted(my_list, key = keyfunc)
groups = []
for k, g in groupby(ls, keyfunc):
groups.append([n['name'] for n in g])
>>> groups
[['item4'], ['item1', 'item6'], ['item5'], ['item2', 'item3']]
样本运行:
>>> sorted(map(keyfunc, my_list))
[[('color', 'black'), ('property', 'value1')],
[('color', 'white')],
[('color', 'white')],
[('color', 'white'), ('custom', 'valueA'), ('property', 'value1')],
[('color', 'white'), ('property', 'value1')],
[('color', 'white'), ('property', 'value1')]]
>>> ls
[{'data': {'color': 'black', 'property': 'value1'}, 'name': 'item4'},
{'data': {'color': 'white'}, 'name': 'item1'},
{'data': {'color': 'white'}, 'name': 'item6'},
{'data': {'color': 'white', 'property': 'value1', 'custom': 'valueA'}, 'name': 'item5'},
{'data': {'color': 'white', 'property': 'value1'}, 'name': 'item2'},
{'data': {'color': 'white', 'property': 'value1'}, 'name': 'item3'}]
备注:itertools.groupby
中的组只允许包含一个项目。你可以用:
>>> [n for n in groups if len(n) > 1]
[['item1', 'item6'], ['item2', 'item3']]