Python 合并具有相同特征的列表的字典
Python Combining Dictionary of A List having Same Characteristics
我有一个这样的列表
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
我希望结果是一个具有新字典值的列表(如果可能,以最有效的方式),如下所示:
values = [{'id':1, 'x':2, 'y':4, 'z':6}, {'id':2, 'j':5, 'k':10}, {'id':3, 'w':1, 'x':3, 'y':5, 'z':7}]
这种情况应该如何循环。
一个粗略的解决方案:
>>> from itertools import groupby
>>> values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
>>> new_values = []
>>> for g,x in groupby(sorted(','.join('{}|{}'.format(k,v) for k,v in sorted(d.items())) for d in values),lambda x: x[:x.index(',',3)]):
nd = dict([g.split('|')])
nd.update(z[len(g)+1:].split('|') for z in x)
new_values.append(nd)
>>> new_values
[{'y': '4', 'x': '2', 'z': '6', 'id': '1'}, {'k': '10', 'j': '5', 'id': '2'}, {'y': '5', 'x': '3', 'z': '7', 'id': '3', 'w': '1'}]
不是很好的解决方案,但可行
values = [{'id': 1, 'x': 2}, {'id': 1, 'y': 4}, {'id': 1, 'z': 6},
{'id': 2, 'j': 5},
{'id': 2, 'k': 10}, {'id': 3, 'w': 1}, {'id': 3, 'x': 3},
{'id': 3, 'y': 5}, {'id': 3, 'z': 7}]
# get all unique possible keys
unique_keys = set((x['id'] for x in values))
result = []
for value in unique_keys:
new_dict = dict(id=value)
for old_dict in values:
if old_dict['id'] == value:
new_dict.update(old_dict)
result.append(new_dict)
print(result)
打印结果:
{'id': 1, 'z': 6, 'x': 2, 'y': 4}, {'j': 5, 'id': 2, 'k': 10}, {'x': 3, 'y': 5, 'id': 3, 'w': 1, 'z': 7}]
解决方案 collections.defaultdict
:
from collections import defaultdict
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
d = defaultdict(list)
for val in values:
d[val['id']].append(val)
result = []
for key in d:
temp = {}
for x in d[key]:
temp.update(x)
result.append(temp)
print(result)
哪些输出:
[{'id': 1, 'x': 2, 'y': 4, 'z': 6}, {'id': 2, 'j': 5, 'k': 10}, {'id': 3, 'w': 1, 'x': 3, 'y': 5, 'z': 7}]
使用 PEP 448 中提出并从 Python 3.5
开始可用的新语法
from itertools import groupby
from operator import itemgetter
groups = groupby(values, itemgetter('id'))
new_list = []
for k,g in groups:
z = {}
for x in g:
z = {**z,**x}
new_list.append(z)
print(new_list)
这是我的方法:
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
dict_1={}
for i in values:
if i['id'] not in dict_1:
dict_1[i['id']]=[{k:l} for k,l in i.items()]
else:
dict_1[i['id']].append({k:l for k,l in i.items() if k!='id'})
print(dict_1)
输出:
{1: [{'id': 1}, {'x': 2}, {'y': 4}, {'z': 6}], 2: [{'j': 5}, {'id': 2}, {'k': 10}], 3: [{'w': 1}, {'id': 3}, {'x': 3}, {'y': 5}, {'z': 7}]}
我有一个这样的列表
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
我希望结果是一个具有新字典值的列表(如果可能,以最有效的方式),如下所示:
values = [{'id':1, 'x':2, 'y':4, 'z':6}, {'id':2, 'j':5, 'k':10}, {'id':3, 'w':1, 'x':3, 'y':5, 'z':7}]
这种情况应该如何循环。
一个粗略的解决方案:
>>> from itertools import groupby
>>> values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
>>> new_values = []
>>> for g,x in groupby(sorted(','.join('{}|{}'.format(k,v) for k,v in sorted(d.items())) for d in values),lambda x: x[:x.index(',',3)]):
nd = dict([g.split('|')])
nd.update(z[len(g)+1:].split('|') for z in x)
new_values.append(nd)
>>> new_values
[{'y': '4', 'x': '2', 'z': '6', 'id': '1'}, {'k': '10', 'j': '5', 'id': '2'}, {'y': '5', 'x': '3', 'z': '7', 'id': '3', 'w': '1'}]
不是很好的解决方案,但可行
values = [{'id': 1, 'x': 2}, {'id': 1, 'y': 4}, {'id': 1, 'z': 6},
{'id': 2, 'j': 5},
{'id': 2, 'k': 10}, {'id': 3, 'w': 1}, {'id': 3, 'x': 3},
{'id': 3, 'y': 5}, {'id': 3, 'z': 7}]
# get all unique possible keys
unique_keys = set((x['id'] for x in values))
result = []
for value in unique_keys:
new_dict = dict(id=value)
for old_dict in values:
if old_dict['id'] == value:
new_dict.update(old_dict)
result.append(new_dict)
print(result)
打印结果:
{'id': 1, 'z': 6, 'x': 2, 'y': 4}, {'j': 5, 'id': 2, 'k': 10}, {'x': 3, 'y': 5, 'id': 3, 'w': 1, 'z': 7}]
解决方案 collections.defaultdict
:
from collections import defaultdict
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
d = defaultdict(list)
for val in values:
d[val['id']].append(val)
result = []
for key in d:
temp = {}
for x in d[key]:
temp.update(x)
result.append(temp)
print(result)
哪些输出:
[{'id': 1, 'x': 2, 'y': 4, 'z': 6}, {'id': 2, 'j': 5, 'k': 10}, {'id': 3, 'w': 1, 'x': 3, 'y': 5, 'z': 7}]
使用 PEP 448 中提出并从 Python 3.5
开始可用的新语法from itertools import groupby
from operator import itemgetter
groups = groupby(values, itemgetter('id'))
new_list = []
for k,g in groups:
z = {}
for x in g:
z = {**z,**x}
new_list.append(z)
print(new_list)
这是我的方法:
values = [{'id':1, 'x':2}, {'id':1, 'y':4}, {'id':1, 'z':6}, {'id':2, 'j':5},
{'id':2, 'k':10}, {'id':3, 'w':1}, {'id':3, 'x':3}, {'id':3, 'y':5}, {'id':3, 'z':7}]
dict_1={}
for i in values:
if i['id'] not in dict_1:
dict_1[i['id']]=[{k:l} for k,l in i.items()]
else:
dict_1[i['id']].append({k:l for k,l in i.items() if k!='id'})
print(dict_1)
输出:
{1: [{'id': 1}, {'x': 2}, {'y': 4}, {'z': 6}], 2: [{'j': 5}, {'id': 2}, {'k': 10}], 3: [{'w': 1}, {'id': 3}, {'x': 3}, {'y': 5}, {'z': 7}]}