合并重复列表的词典项值

时间:2016-04-21 12:18:45

标签: python django list dictionary merge

我有以下词典列表,其中包含重复值(教练)。

d = [
    {"players": [{"id": 179, "name": "Santosh"}], "coach": "Xavi Alonso"}, 
    {"players": [{"id": 180, "name": "Hari"}], "coach": "Xavi Alonso"}, 
    {"players": [{"id": 175, "name": "Hitman"}], "coach": "Anna Puyol"}
]

我想根据教练名称合并重复项目。我怎样才能做到这一点?

def exportplayers(request):
    d = [
        {"players": [{"id": 179, "name": "Santosh"}, {"id": 180, "name": "Hari"}], "coach": "Xavi Alonso"}, 
        {"players": [{"id": 175, "name": "Hitman"}], "coach": "Anna Puyol"}
    ]


    return HttpResponse(json.dumps(d))

3 个答案:

答案 0 :(得分:2)

一种可能的解决方案是构建一个辅助字典,其中coach为关键字,players列为值

d = [
    {"players": [{"id": 179, "name": "Santosh"}], "coach": "Xavi Alonso"},
    {"players": [{"id": 180, "name": "Hari"}], "coach": "Xavi Alonso"},
    {"players": [{"id": 175, "name": "Hitman"}], "coach": "Anna Puyol"}
]
aux = collections.defaultdict(list)
for e in d:
    aux[e['coach']].append(e['players'][0])

aux现在是:

>>> aux
defaultdict(<type 'list'>, {'Xavi Alonso': [[{'id': 179, 'name': 'Santosh'}], [{'id': 180, 'name': 'Hari'}]], 'Anna Puyol': [[{'id': 175, 'name': 'Hitman'}]]})

然后你可以使用列表理解

来建立你的返回值
[{'players':v, 'coach':k} for k,v in aux.items()]

哪个是

[{'players': [{'id': 179, 'name': 'Santosh'}, {'id': 180, 'name': 'Hari'}], 'coach': 'Xavi Alonso'}, {'players': [{'id': 175, 'name': 'Hitman'}], 'coach': 'Anna Puyol'}]

答案 1 :(得分:1)

像这样:

coaches = []
new_d = []

for dic in d:
    if dic["coach"] in coaches:
        ind = coaches.index(dic["coach"])
        new_d[ind]["players"].append(dic["players"])
    else:
        coaches.append(dic["coach"])        
        new_d.append(dic)

print new_d

但是这里字典的使用变得奇怪......上课怎么样?

答案 2 :(得分:1)

您可以使用itertools模块中的groupbyoperator模块中的itemgetter来执行此操作。将 grouby 操作视为从记录中返回连续键和组的方法。为了使它工作,你需要列表中的“项目”按照“{coach”值进行排序,这是sorted函数在这里所做的。当然,您需要提供一个键函数来自定义排序顺序,一种方法是使用像sorted(d, key=lambda _: _["coach"])这样的lambda表达式,但我更喜欢使用sorted(d, key=itemgetter('coach'))的替代方法。据说你还需要提供groupby的关键参数,这是一个计算documentation中提到的每个元素的关键值的函数,并且你可以再次使用key=itemgetter("coach")

from itertools import groupby
from operator import itemgetter



def exportplayers(request):
    d = [
        {"players": [{"id": 179, "name": "Santosh"}, {"id": 180, "name": "Hari"}], "coach": "Xavi Alonso"}, 
        {"players": [{"id": 175, "name": "Hitman"}], "coach": "Anna Puyol"}
    ]
    my_list = []
    for g, data in groupby(sorted(d, key=itemgetter('coach')),  key=itemgetter('coach')):
        my_list.append({"coach": g, "players": [player for item in data for player in item["players"]]})
    return HttpResponse(json.dumps(my_list))

使用lambda表达式作为关键函数进行演示:

>>> from itertools import groupby
>>> d = [
...     {"players": [{"id": 179, "name": "Santosh"}], "coach": "Xavi Alonso"}, 
...     {"players": [{"id": 180, "name": "Hari"}], "coach": "Xavi Alonso"}, 
...     {"players": [{"id": 175, "name": "Hitman"}], "coach": "Anna Puyol"}
... ]
>>> sorted_d = sorted(d, key=lambda _: _['coach'])
>>> for g, data in groupby(sorted_d, key=lambda _: _['coach']):
...     print({"coach": g, "players": [player for item in data for player in item["players"]]})
... 
{'coach': 'Anna Puyol', 'players': [{'id': 175, 'name': 'Hitman'}]}
{'coach': 'Xavi Alonso', 'players': [{'id': 179, 'name': 'Santosh'}, {'id': 180, 'name': 'Hari'}]}