2013-02-26 23 views
5

Ho una lista di dit in python 2.7.elenco python di dizionari trovare duplicati in base al valore

a =[{'id': 1,'desc': 'smth'}, 
    {'id': 2,'desc': 'smthelse'}, 
    {'id': 1,'desc': 'smthelse2'}, 
    {'id': 1,'desc': 'smthelse3'},....] 

vorrei andare attraverso la lista e trovare quelle dicts che hanno lo stesso valore - id (per esempio, id = 1) e creare una nuova dict

b = [{'id':1, 'desc' : [smth, smthelse2,smthelse3]}, 
    {'id': 2, 'desc': 'smthelse'}] 

spero di essere stato abbastanza chiaro

vi ringrazio molto per i vostri suggerimenti

+0

I dizionari contengono sempre due chiavi, 'id' e' desc', o il problema è più generale? – NPE

+0

È importante conservare l'ordine nell'elenco? – entropy

+0

@NPE - il problema sarà "più generale" (e brutto) se OP mantiene stringhe per voci singole e liste per più voci. – eumiro

risposta

3

E 'meglio tenere i valori "decrescente", come le liste ovunque anche se contengono solo un singolo elemento. In questo modo puoi fare

for d in b: 
    print d['id'] 
    for desc in d['desc']: 
     print desc 

Questo funzionerebbe anche per le stringhe, restituendo solo i singoli caratteri, che non è quello che vuoi.

E ora la soluzione dando un elenco di dicts di elenchi:

a =[{'id': 1,'desc': 'smth'},{'id': 2,'desc': 'smthelse'},{'id': 1,'desc': 'smthelse2'},{'id': 1,'desc': 'smthelse3'}] 

c = {} 
for d in a: 
    c.setdefault(d['id'], []).append(d['desc']) 
b = [{'id': k, 'desc': v} for k,v in c.iteritems()] 

b è ora:

[{'desc': ['smth', 'smthelse2', 'smthelse3'], 'id': 1}, 
{'desc': ['smthelse'], 'id': 2}] 
+0

Cosa devo fare se devo cercare ditali uguali basati su più di un solo tasto. Ho lo stesso problema ma l'ID univoco si basa su 5 chiavi? – Yebach

+0

So che è tardi, ma puoi avere una tupla come tasto dict. – jangeador

9

si può provare:

key = operator.itemgetter('id') 

b = [{'id': x, 'desc': [d['desc'] for d in y]} 
    for x, y in itertools.groupby(sorted(a, key=key), key=key)] 
0
from collections import defaultdict 

d = defaultdict(list) 
for x in a: 
    d[x['id']].append(x['desc']) # group description by id 
b = [dict(id=id, desc=desc if len(desc) > 1 else desc[0]) 
    for id, desc in d.items()] 

Per conservare l'ordine:

b = [] 
for id in (x['id'] for x in a): 
    desc = d[id] 
    if desc: 
     b.append(dict(id=id, desc=desc if len(desc) > 1 else desc[0])) 
     del d[id] 
Problemi correlati