2010-06-09 7 views
5

Załóżmy, że mam słownik, którego kluczami są ciągi. Jak mogę efektywnie utworzyć nowy słownik z tego, który zawiera tylko klucze obecne na jakiejś liście?Wybieranie artykułów ze słownika kluczem wydajnie w Pythonie

na przykład:

# a dictionary mapping strings to stuff 
mydict = {'quux': ..., 
      'bar': ..., 
      'foo': ...} 

# list of keys to be selected from mydict 
keys_to_select = ['foo', 'bar', ...] 

Sposób wymyśliłem to:

filtered_mydict = [mydict[k] for k in mydict.keys() \ 
        if k in keys_to_select] 

ale myślę, że jest to bardzo nieefektywne, ponieważ: (1) wymaga wyliczanie klawiszy z klawiszami() , (2) wymaga wyszukania k w keys_to_select za każdym razem. przynajmniej jedno z nich można by uniknąć, pomyślałbym. jakieś pomysły? W razie potrzeby mogę też używać scipy/numpy.

Odpowiedz

15
dict((k, mydict[k]) for k in keys_to_select) 

jeśli wiesz, że wszystkie klawisze do wyboru są również klawiszami w mydict; jeśli to nie jest przypadek,

dict((k, mydict[k]) for k in keys_to_select if k in mydict) 
+1

Przy zastosowaniu „jeśli k w mydict” jak to, czy Python wykonać typu has_key odnośnika, czy też przekształcić klucze do listy/iterable i pętli nad nimi? Jeśli to drugie, "jeśli mydict.has_key (k)" może być bardziej wydajne, nie? (Nie znalazłem jeszcze żadnej dokumentacji, aby objaśnić, tak czy inaczej, umiejętności Google nie powiodły się). – pycruft

+1

Aby odpowiedzieć na własne pytanie, użycie "k in dict" jest identyczne z użyciem "dict.has_key (k)" zgodnie z http://www.python.org/dev/peps/pep-0234/ – pycruft

+2

@pycruft, yep i, jak potwierdziło 'timeit' cqn (' python -mtimeit -s'd = dict.fromkeys (range (99)) '23 in d'etc), 'in' jest w rzeczywistości około dwa razy szybsze jako 'has_key' (zapisuje wyszukiwanie nazwanego atrybutu za każdym razem, co jest mniej więcej tą samą operacją, co loolup dict). Nigdy nie ma powodu, aby używać 'has_key' więcej i zostało usunięte z Pythona 3. –

Powiązane problemy