Mi lista actual

my_list = [
   {'id': 1, 'val': [6]},
   {'id': 2, 'val': [7]},
   {'id': 3, 'val': [8]},
   {'id': 2, 'val': [9]},
   {'id': 1, 'val': [10]},
]

Salida deseada:

my_list = [
   {'id': 1, 'val': [6, 10]},
   {'id': 2, 'val': [7, 9]},
   {'id': 3, 'val': [8]},
]

Lo que probé hasta ahora:

    my_new_list = []
    id_set = set()

    for d in my_list:
        if d['id'] not in id_set:
            id_set.add(d['id'])
            temp = {'id': d['id'], 'val': d['val']}
            my_new_list.append(temp)
        else:
             # loop over the new list and find the dict which already have d['id'] and update by appending value
             # but this is not efficient

Cualquier otro enfoque más eficiente o puede ser una función incorporada que no conozco.

PD: ¡El orden es importante!

3
Wendy 9 may. 2016 a las 10:05

3 respuestas

La mejor respuesta

.setdefault() es tu amiga:

(Deberíamos usar collections.OrderedDict para recordar el orden en que se insertaron las claves por primera vez).

>>> import collections

>>> result = collections.OrderedDict()
>>> for d in my_list:
...     result.setdefault(d["id"], []).extend(d["val"])

>>> lst = []
>>> for k, v in result.items():
...     lst.append({"id": k, "val": v})
4
ozgur 9 may. 2016 a las 07:37

El mismo enfoque que ozgur, pero con collections.defaultdict:

>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for dd in my_list:
        d[dd['id']].extend(dd['val'])
>>> d
defaultdict(<type 'list'>, {1: [6, 10], 2: [7, 9], 3: [8]})
>>>
>>> lst = []
>>> for k,v in d.iteritems():
        lst.append({'id':k, 'val':v})

>>> lst
[{'id': 1, 'val': [6, 10]}, {'id': 2, 'val': [7, 9]}, {'id': 3, 'val': [8]}]
>>>
1
Community 23 may. 2017 a las 12:31

Puede usar itertools.groupby para ordenar y Agrupe el list original por 'id' y acumule el 'val' para cada grupo:

from itertools import groupby

key_fnc = lambda d: d['id']
result = [
    {'id': k, 'val': sum([d['val'] for d in g], [])} 
        for k, g in groupby(sorted(my_list, key=key_fnc), key=key_fnc)
]
0
schwobaseggl 9 may. 2016 a las 07:19