2012-11-06 29 views
7

Mam listę słowników, takich jak:Usuwanie kluczowych wartości par z listy słowników

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

muszę usunąć wszystkie kluczowe wartości par ze wszystkich słowników gdzie kluczem jest równa mykey1. Mógłbym to zrobić, przechodząc przez instrukcję del, ale zastanawiam się, jak utworzyć nową listę za pomocą wyrażeń listowych lub lambd, które po prostu usuną wszystkie pary wartości klucza, gdzie kluczem był mykey1.

Dziękujemy

Odpowiedz

14

Jeśli naprawdę chcesz użyć wyrażeń listowych, połączyć je ze zrozumieniem dict:

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

Zastępca .iteritems() dla .items() jeśli jesteś na Pythona 3.

na Python 2.6 i poniżej zalecana używać:

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

składnię zrozumienie {key: value ...} DICT wprowadzono tylko Pythonie 2,7 3.

+1

I zastąpić dict komp z 'dict ((k, v) dla k, v w d.iteritems() jeśli k! = 'Mykey1')' jeśli jesteś na python2. 6 lat lub więcej. – mgilson

+0

@mgilson Jeśli mój warunek jest taki, że k powinno być w określonej krotce, można to zrobić: {dict ((k, v) dla k, v w d.iteritems(), jeśli k w mytuple)} tak? Ponieważ kiedy to zrobię, otrzymuję: nieodmienny typ: 'dict' – dublintech

+2

@dublintech: używasz niewłaściwej składni; to nawiasy kwadratowe wokół całego, a nie nawiasy klamrowe: '[dict ((k, v) dla k, v w d.iteritems() jeśli k w mytuple) dla d w mylist]'. Wyrażenie "k in mytuple" jest w porządku. –

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) 

lub

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

Zamiast używać del, zdecydowałem się na dict.pop od pop będzie tłumić KeyError jeśli klucz nie istnieje.


Jeśli naprawdę chcesz tylko uzyskać pewne klucze, staje się to nieco łatwiejsze.

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 ] 

co podnosi KeyError jeśli klawisze nie są w starym dict

czyli

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

który będzie również dodać key:None jeśli key nie jest w starej dict. Jeśli nie chcesz tego None, można zrobić:

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

zależności jaki procent słownika jesteś tym/z wyłączeniem i wielkości słowników, to może być nieco szybciej niż roztworu przez @ MartijnPieters.

1

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

+2

Zmienia to starą listę i słowniki w miejscu, * i * nowa lista będzie składać się tylko z usuniętych wartości. –

+0

prawda, nie jest to najlepsze rozwiązanie, jeśli oryginał musi zostać zachowany. –

+0

* I * zrozumienie listy nie przynosi niczego użytecznego. –

Powiązane problemy