2013-02-26 14 views
5

Mam listę dyktuje w Pythonie 2.7.Python lista słowników znaleźć duplikaty na podstawie wartości

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

Chciałbym iść koryta listę i znaleźć te dicts, które mają taką samą wartość - ID (np id = 1) i utworzyć nowe dict

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

Mam nadzieję, że było wystarczająco jasne

bardzo dziękuję za sugestie

+0

Czy słowniki zawsze zawierają dwa klucze, "id" i "opis", czy też problem jest bardziej ogólny? – NPE

+0

Czy ważne jest zachowanie porządku na liście? – entropy

+0

@NPE - problem będzie "bardziej ogólny" (i brzydki), jeśli OP zawiera ciągi dla pojedynczych wpisów i list dla wielu wpisów. – eumiro

Odpowiedz

3

lepiej jest zachować wartości „desc” jako list wszędzie, nawet jeżeli zawierają one tylko jeden element. W ten sposób można zrobić

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

to będzie działać na smyczki też po prostu powrocie poszczególne znaki, które nie jest tym, co chcesz.

A teraz rozwiązanie daje listę dicts list:

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 jest teraz:

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

Co, jeśli muszę szukać równych dyktatur na podstawie więcej niż jednego klucza. Mam ten sam problem, ale unikalny identyfikator opiera się na 5 klawiszach? – Yebach

+0

Wiem, że jest późno, ale możesz mieć krotkę jako klucz do dyktowania. – jangeador

9

Można spróbować:

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()] 

Aby zachowaj zamówienie:

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] 
Powiązane problemy