Saltar al contenido

Agrupar y agregar una lista de diccionarios por múltiples keys

Sé libre de divulgar nuestro sitio y códigos en tus redes, necesitamos tu ayuda para aumentar nuestra comunidad.

Solución:

Usando Python puro, puede insertar en un OrderedDict para conservar el orden de inserción:

from collections import OrderedDict

d = OrderedDict()
for l in lst:
    d.setdefault((l['number'], l['favorite']), set()).add(l['color'])

['number': k[0], 'favorite': k[1], 'color': v.pop() if len(v) == 1 else v 
    for k, v in d.items()]   
# ['color': 'green', 'red', 'favorite': False, 'number': 1,
#  'color': 'red', 'favorite': True, 'number': 1,
#  'color': 'red', 'favorite': False, 'number': 2]

Esto también se puede hacer con bastante facilidad usando los pandas. GroupBy API:

import pandas as pd

d = (pd.DataFrame(lst)
       .groupby(['number', 'favorite'])
       .color
       .agg(set)
       .reset_index()
       .to_dict('r'))
d
# ['color': 'green', 'red', 'favorite': False, 'number': 1,
#  'color': 'red', 'favorite': True, 'number': 1,
#  'color': 'red', 'favorite': False, 'number': 2]

Si la condición de un string para un solo elemento es necesario, puede utilizar

['color': (lambda v: v.pop() if len(v) == 1 else v)(d_.pop('color')), **d_ 
     for d_ in d]
# ['color': 'green', 'red', 'favorite': False, 'number': 1,
#  'color': 'red', 'favorite': True, 'number': 1,
#  'color': 'red', 'favorite': False, 'number': 2]

Una solución en Python puro sería usar un defaultdict con un compuesto key. Podrías usar eso para fusionar tus valores. Luego puede crear una lista nuevamente a partir de ese diccionario.

from collections import defaultdict

dct = defaultdict([])

for entry in lst:
    dct[(entry['number'], entry['favorite'])].append(entry['color'])

lst = ['number': key[0], 'favorite': key[1], color: value if len(value) > 1 else value[0]
    for key, value in dct.items()]

O groupby de itertools:

import itertools
lst = [
'number': 1, 'favorite': False, 'color': 'red',
'number': 1, 'favorite': False, 'color': 'green',
'number': 1, 'favorite': False, 'color': 'red',
'number': 1, 'favorite': True, 'color': 'red',
'number': 2, 'favorite': False, 'color': 'red']
l=[list(y) for x,y in itertools.groupby(sorted(lst,key=lambda x: (x['number'],x['favorite'])),lambda x: (x['number'],x['favorite']))]
print([k:(v if k!='color' else list(set([x['color'] for x in i]))) for k,v in i[0].items() for i in l])

Producción:

['number': 1, 'favorite': False, 'color': ['green', 'red'], 'number': 1, 'favorite': True, 'color': ['red'], 'number': 2, 'favorite': False, 'color': ['red']]

valoraciones y reseñas

Si guardas alguna desconfianza o disposición de regenerar nuestro división te recomendamos ejecutar una aclaración y con deseo lo interpretaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *