2016-09-17 6 views
3

Der Einfachheit halber habe ich 2 Listen in einer Liste zur Verfügung gestellt, aber ich habe tatsächlich mit hundert Listen in einer Liste, die jeweils eine beträchtliche Anzahl von Wörterbüchern enthält. Ich möchte nur den Wert des 'Status'-Schlüssels im 1. Wörterbuch bekommen, ohne irgendwelche anderen Wörterbücher in dieser Liste zu überprüfen (da ich weiß, dass sie alle denselben Wert bei diesem Schlüssel enthalten). Dann werde ich in jedem großen Wörterbuch eine Art Clustering durchführen. Ich muss alle 'Titel' Werte effizient verketten. Gibt es eine Möglichkeit, meinen Code eleganter und schneller zu machen?schneller und mehr 'Pythonic' Liste der Wörterbücher

ich habe:

nested = [ 
    [ 
     {'id': 287, 'title': 'hungry badger', 'status': 'High'}, 
     {'id': 437, 'title': 'roadtrip to Kansas','status': 'High'} 
    ], 
    [ 
     {'id': 456, 'title': 'happy title here','status': 'Medium'}, 
     {'id': 342,'title': 'soft big bear','status': 'Medium'} 
    ] 
] 

Ich mag würde:

result = [ 
    { 
     'High': [ 
      {'id': 287, 'title': 'hungry badger'}, 
      {'id': 437, 'title': 'roadtrip to Kansas'} 
     ] 
    }, 
    { 
     'Medium': [ 
      {'id': 456, 'title': 'happy title here'}, 
      {'id': 342, 'title': 'soft big bear'} 
     ] 
    } 
] 

Was ich versucht:

for oneList in nested: 
    result= {} 
    for i in oneList:   
     a= list(i.keys()) 
     m= [i[key] for key in a if key not in ['id','title']] 
     result[m[0]]=oneList 
     for key in a: 
      if key not in ['id','title']: 
       del i[key] 

Antwort

2
from itertools import groupby  
result = groupby(sum(nested,[]), lambda x: x['status']) 

Wie es funktioniert:

sum(nested,[]) verkettet alle äußeren Listen zu einer großen Liste der Wörterbücher

groupby(, lambda x: x['status']) Gruppen alle Objekte durch ihre Eigenschaft status

Hinweis itertools.groupby einen Generator zurückgibt (keine Liste), so dass, wenn Sie wollen materialisieren den Generator Sie müssen etwas wie folgt tun.

from itertools import groupby  
result = groupby(sum(nested,[]), lambda x: x['status']) 
result = {key:list(val) for key,val in result} 
+0

omg! @[email protected] Beeindruckend. Du bist so schnell mit der Lösung. Vielen Dank !!!! Funktioniert perfekt. – el347

+1

Eins: Verwenden Sie nicht 'sum (verschachtelt, [])', jemals. Es ist der langsamste Weg, um zu flattern, und es wird langsamer, je mehr Sie flacht machen (es erstellt 'n' temporäre' liste', wächst jedes Mal). Sie verwenden bereits 'itertools', und Sie iterieren die Ergebnisse (benötigen Sie keine echte' list'), verwenden Sie einfach 'itertools.chain.from_iterable', um flacher zu werden (und weil' lambda' böse ist/slow, wenn nicht benötigt, 'operator.itemgetter' für' key'): 'groupby (chain.from_iterable (verschachtelt), itemgetter ('status'))'. ['sum (x, [])' ist _slow_ (siehe Kommentare)] (http://stackoverflow.com/a/39520827/364696). – ShadowRanger

+1

@ShadowRanger Danke, Mann! Habe das gerade gemacht: von itertools import chain; Import-Operator; s = groupby (chain.from_iterable (Ergebnisse), key = operator.itemgetter ('status')); für Schlüssel, grp in s: print (Schlüssel, Liste (grp)) Alles gut. – el347

2

Sie könnten eine defaultdict für jede verschachtelte Liste machen:

import collections 
nested = [ 
[{'id': 287, 'title': 'hungry badger', 'status': 'High'}, 
{'id': 437, 'title': 'roadtrip to Kansas','status': 'High'}],  
[{'id': 456, 'title': 'happy title here','status': 'Medium'}, 
{'id': 342,'title': 'soft big bear','status': 'Medium'}] ] 
result = [] 
for l in nested: 
    r = collections.defaultdict(list) 
    for d in l: 
     name = d.pop('status') 
     r[name].append(d) 
    result.append(r) 

Dies ergibt folgende result:

>>> import pprint 
>>> pprint.pprint(result) 
[{'High': [{'id': 287, 'title': 'hungry badger'}, 
      {'id': 437, 'title': 'roadtrip to Kansas'}]}, 
{'Medium': [{'id': 456, 'title': 'happy title here'}, 
      {'id': 342, 'title': 'soft big bear'}]}] 
+0

Ehrfürchtig. Tnx! Hier lernt man jeden Tag neu. Hehe. Die Lösung von iertools sieht so gut aus. reduziert die Komplexität. Ihre Antwort hat mich über collections.defaultdict() gelehrt. Danke noch einmal. – el347

+0

oh nett! Ur-Lösung entfernt den Status und tut, was ich gefragt habe. Ich werde die Zeit für beide Zeit nehmen und auch ein wenig mehr mit der Gruppe von itertools spielen ... Danke für die Hilfe, Mann! – el347

Verwandte Themen