2012-11-06 16 views
7

Ho una lista di dizionari quali:Rimozione chiave valori coppie da un elenco di dizionari

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

ho bisogno di rimuovere tutti i valori di coppie di chiavi da tutti i dizionari in cui la chiave è pari a mykey1. Potrei farlo collegando e usando l'istruzione del, ma mi chiedo come creerei una nuova lista usando le list comprehensions o lambda che rimuoveranno tutte le coppie di valori chiave in cui la chiave era mykey1.

Molte grazie

risposta

14

Se davvero si vuole utilizzare un elenco di comprensione, combinarlo con la comprensione dict:

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

sostituto .iteritems() per .items() se siete su Python 3.

su Python 2.6 e di seguito si dovrebbe utilizzare:

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

come la sintassi di comprensione {key: value ...} dict è stato introdotto solo in Python 2.7 e 3.

+1

E sostituire il bozzetto dict con 'dict ((k, v) per k, v in d.iteritems() se k! = 'Mykey1')', se siete su python2. 6 o più vecchio. – mgilson

+0

@mgilson Se la mia condizione è che k sia in una specifica tupla, è corretto farlo: {dict ((k, v) per k, v in d.iteritems() se k in mytuple)} yeah? Perché quando lo faccio, ottengo: tipo inattaccabile: 'dict' – dublintech

+2

@dublintech: stai usando la sintassi sbagliata; è parentesi quadre intorno al tutto, non parentesi graffe: '[dict ((k, v) per k, v in d.iteritems() se k in mytuple) per d in mylist]'. L'espressione 'k in mytuple' va bene. –

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) 

o

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

Piuttosto che usare del, ho optato per dict.pop dal pop sopprimerà l'KeyError se la chiave non esiste.


Se si desidera ottenere solo determinate chiavi, questo diventa un po 'più semplice.

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 ] 

che solleva KeyError se le chiavi non sono nella vecchia dict

Oppure:

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

che sarà anche aggiungere key:None se key non è nel vecchio dict. Se non si desidera che None, si potrebbe fare:

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

A seconda di quale percentuale del dizionario che stai con/senza e la dimensione dei dizionari, questo potrebbe essere leggermente più veloce rispetto alla soluzione da @ MartijnPieters.

1

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

+2

Questo modifica il vecchio elenco e i dizionari in posizione, * e * il nuovo elenco includerà solo i valori rimossi. –

+0

true, non la soluzione migliore se l'originale deve essere conservato –

+0

* E * la comprensione della lista non produce nulla di utile. –

Problemi correlati