2012-11-06 2 views
7

Ich habe eine Liste von Wörterbüchern, wie:Entfernen von Schlüsselwerten Paare aus einer Liste von Wörter

[{'mykey1':'myvalue1', 'mykey2':'myvalue2'}, {'mykey1':'myvalue1a', 'mykey2':'myvalue2a'}] 

Ich brauche alle Schlüsselwerte Paare von allen Wörter zu entfernen, wo der Schlüssel zu mykey1 gleich ist. Ich könnte dies tun, indem ich die Del-Anweisung durchlaufe und benutze, aber ich frage mich, wie ich eine neue Liste mit Listen-Comprehensions oder Lambdas erstellen würde, die einfach alle Schlüssel-Wert-Paare entfernen würden, wo der Schlüssel mykey1 war.

Vielen Dank

Antwort

14

Wenn Sie wirklich wollen, eine Liste Verständnis verwenden, kombinieren Sie es mit einem dict Verständnis:

[{k: v for k, v in d.iteritems() if k != 'mykey1'} for d in mylist] 

Ersatz .iteritems() für .items(), wenn Sie auf Python sind 3.

auf Python 2.6 und unten sollten Sie verwenden:

[dict((k, v) for k, v in d.iteritems() if k != 'mykey1') for d in mylist] 

als die {key: value ...} dict Verständnis Syntax nur in Python eingeführt wurde 2,7 und 3.

+1

und ersetze die dict comp mit 'dict ((k, v) für k, v in d.iteritems(), wenn k! = 'Mykey1')', wenn Sie auf python2. 6 oder älter. – mgilson

+0

@mgilson Wenn meine Bedingung ist, dass k in einem bestimmten Tupel sein soll, ist es in Ordnung zu tun: {dict ((k, v) für k, v in d.iteritems() wenn k in mytuple)} yeah? Denn wenn ich das tue, bekomme ich: nicht hashbar Typ: 'dict' – dublintech

+2

@dublintech: Sie verwenden die falsche Syntax; Es sind eckige Klammern um die ganze, nicht geschweifte Klammern: '[dict ((k, v) für k, v in d.iteritems() wenn k in mytuple) für d in mistel]'. Der Ausdruck "k in mytuple" ist in Ordnung. –

4
def new_dict(old_dict): 
    n = old_dict.copy() 
    n.pop('mykey1',None) 
    return n 

new_list_of_dict = map(new_dict,list_of_dict) 

oder

new_list_of_dict = [ new_dict(d) for d in list_of_dict ] 

Anstatt del verwenden, entschied ich mich für dict.pop seit pop die KeyError unterdrücken, wenn der Schlüssel nicht existiert.


Wenn Sie wirklich nur bestimmte Schlüssel erhalten möchten, wird dies ein bisschen einfacher.

from operator import itemgetter 
tuple_keys = ('key1','key2','key3') 
get_keys = itemgetter(*tuple_keys) 
new_dict_list = [ dict(zip(tuple_keys,get_keys(d)) for d in old_dict_list ] 

die KeyError erhöht, wenn die Schlüssel nicht in der alten dict

Oder:

new_dict_list = [ dict((k,d.get(k,None)) for k in tuple_keys) for d in old_dict_list ] 

die auch key:None wenn key hinzufügen wird, ist nicht in der alten dict. Wenn Sie nicht, dass None möchten, können Sie tun:

new_dict_list = [ dict((k,d[k]) for k in tuple_keys if k in d) for d in old_dict_list ] 

Je nachdem, welche Prozent des Wörterbuchs Sie mit/ohne und die Größe der Wörterbücher, könnte dies sein etwas schneller als die Lösung von @ MartijnPieters.

1

[d.pop('mykey1', None) for d in list]

+2

Dies ändert die alte Liste und die vorhandenen Wörterbücher, * und * die neue Liste besteht nur aus den entfernten Werten. –

+0

wahr, nicht die beste Lösung, wenn das Original erhalten werden muss –

+0

* Und * Ihre Liste Verständnis produziert nichts nützliches. –