2016-06-02 12 views
0

Ich habe eine Liste der Folowing Form:Liste der Wörterbuch-Manipulation in Python

oldlist = [{'x': 1, 'y':2},{'x':2, 'y':2},{'x':1, 'y':3},{'x':1, 'y':2},{'x':3, 'y':4}] 

in

final = [{'x':1,'y':[2,3,2],'count':3},{'x':2,'y':[2],'count':1},{'x':3,'y':[4],'count':1}] 

umgewandelt werden Ich habe

versucht
oldlist = [{'x': {'a':1,'b':2}, 'y':2},{'x':{'a':6,'b':7}, 'y':2},{'x':{'a':1,'b':2}, 'y':3},{'x':{'a':1,'b':2}, 'y':2},{'x':{'a':10,'b':11}, 'y':4}] 
list1=[] 
list2=[] 
list3=[] 
s = set([d['x'] for d in oldlist]) 
news=list(s) 
for item in oldlist: 
if item['x'] == news[0]: 
     list1.append(item['y']) 

if item['x'] == news[1]: 
     list2.append(item['y']) 

if item['x'] == news[2]: 
     list3.append(item['y']) 
final=[] 
dic1 = {'x':news[0],'y':list1,'count':len(list1)} 
dic2 = {'x':news[1],'y':list2,'count':len(list2)} 
dic3 = {'x':news[2],'y':list3,'count':len(list3)} 
final.append(dic1) 
final.append(dic2) 
final.append(dic3) 
print final 

gibt es eine einfachere Weg, es zu tun? Plus hier wusste ich, dass x nur drei Werte haben kann, also habe ich drei Variablen list1, list2 und list3 erstellt. Was ist, wenn x mehrere andere Werte haben kann und ich eine ähnliche Liste von Wörterbüchern wie final finden muss? Es sollte auch für Strings funktionieren!

+0

Sie können eine 'list' aus dem' Set' mit 's_list = sortiert (n)' machen. (Oder nur 's_list = Liste (n)' wenn Sie sich nicht darum kümmern, sortiert zu werden.) – leekaiinthesky

+0

@leekaiinthesky Das wird für dieses Beispiel funktionieren, aber nicht für andere, die verschiedene andere Werte von x haben können. – glitterati

Antwort

4

Sie können die dicts zu defaultdict wo Schlüssel x von ursprünglichen dicts und Wert ist Liste der verwandten Werte y sammeln. Dann Verständnis verwendet Liste um das Endergebnis zu erzeugen:

from collections import defaultdict 

l = [{'x':1, 'y':2},{'x':2, 'y':2},{'x':1, 'y':3},{'x':1, 'y':2},{'x':3, 'y':4}] 
res = defaultdict(list) 
for d in l: 
    res[d['x']].append(d['y']) 
final = [{'x': k, 'y': v, 'count': len(v)} for k, v in res.items()] # [{'y': [2, 3, 2], 'x': 1, 'count': 3}, {'y': [2], 'x': 2, 'count': 1}, {'y': [4], 'x': 3, 'count': 1}] 
+0

Dies ist der Fehler, den ich bei der Ausführung Ihres Codes erhalte. TypeError: nicht hashbarer Typ: 'dict' – glitterati

+0

@glitterati Hast du die Lösung als solche ausgeführt oder hast du sie geändert? Könnten Sie versuchen, das Beispiel in eine separate Datei zu kopieren und einzufügen, und versuchen, es auszuführen? – niemmi

+0

Ich habe es ein wenig modifiziert. Eigentlich ist das x-Feld in der alten Liste mein Beispiel ein Wörterbuch. Daher der Fehler. Können Sie bitte vorschlagen, was zu tun ist, wenn x ein diktierendes Element ist und y dasselbe ist. Ich kann die Frage entsprechend ändern, wenn Sie wollen! – glitterati

0

Ok, habe ich hier einen kleinen Trick, um die Arbeit zu tun, es ist nicht die Art und Weise pythonic aber es wird immer noch die Antwort, die Sie wollen. Das Problem war Indexierung? Also ein geändertes s zu t, wobei t eine Liste ist und das Ende des Codes geändert wurde, weil du die Schlüssel in deine Wörterbücher als Strings setzen musst, also x zu 'x' und so weiter.

Siehe die ganze Code unten:

lista = [{'x':1, 'y':2},{'x':2, 'y':2},{'x':1, 'y':3},{'x':1, 'y':2},{'x':3, 'y':4}] 


list1=[] 
list2=[] 
list3=[] 
for d in lista: 
    print(d) 
s = set([d['x'] for d in lista]) 
t = [] 
for element in s: #turn t into a list which has the same ordering as s 
    t.append(element) 
for item in lista: 
    if item['x'] == t[0]: 
      list1.append(item['y']) 

    if item['x'] == t[1]: 
      list2.append(item['y']) 

    if item['x'] == t[2]: 
      list3.append(item['y']) 
final=[] 
dic1 = {'x':t[0],'y':list1,'count':len(list1)} 
dic2 = {'x':t[1],'y':list2,'count':len(list2)} 
dic3 = {'x':t[2],'y':list3,'count':len(list3)} 
final.append(dic1) 
final.append(dic2) 
final.append(dic3) 
print(final) 
+0

Dies funktioniert für dieses Beispiel, aber nicht für andere, wo unterschiedliche Werte von x mehr sein könnten als 3. Das war meine Frage an erster Stelle. – glitterati

+0

Oh, also ändere ein bisschen die Logik: (Sorry, ich habe falsch auf "Enter" geklickt, ich denke immer noch darüber nach, wie ich das lösen kann). –