2009-02-23 25 views
297

Jaki jest najlepszy sposób na rozszerzenie słownika na inny? Na przykład:Python "rozszerzenie" dla słownika

>>> a = { "a" : 1, "b" : 2 } 
>>> b = { "c" : 3, "d" : 4 } 
>>> a 
{'a': 1, 'b': 2} 
>>> b 
{'c': 3, 'd': 4} 

szukam jakiejkolwiek pracy w celu uzyskania tego unikając for pętlę:

{ "a" : 1, "b" : 2, "c" : 3, "d" : 4 } 

pragnę zrobić coś takiego:

a.extend(b) # This does not work 
+22

Wiedziałem, że dla list [], to supose może być pracą dla innych, nie wymagać od ciebie ;-) – FerranB

Odpowiedz

476
+3

Po przeczytaniu dokumentów zrozumie się, dlaczego istnieje "aktualizacja", ale nie "tekst". – georg

+13

należy pamiętać, że update() bezpośrednio modyfikuje dict i zwraca None. – emisilva

+0

Ale co, jeśli chcesz rozszerzyć dict tylko o wartości _nie_ zdefiniowane (tzn. Nie nadpisując istniejących wartości)? Na przykład zaktualizuj dict '{" a ": 2," b ": 3}' with dict '{" b ": 4," c ": 5}', aby dyktować '{" a ": 2," b ": 3," c ": 5}'? Oczywiście możliwe jest użycie 'update()', przenosząc pewne rzeczy dookoła, ale byłoby fajniej gdyby można je było wykonać tylko w jednym wierszu ... – Nearoo

20
a.update(b) 

Dodaje klucze i wartości od b do a, zastępując, jeśli istnieje już wartość klucza.

136

piękny klejnot w this closed question:

W "oneliner sposób", zmieniając ani z dicts wejściowych jest

basket = dict(basket_one, **basket_two) 

dowiedzieć się, co **basket_two (the **) means here.

W przypadku konfliktu elementy z basket_two zastąpią te z basket_one. Jako jednolinijkowe, jest to całkiem czytelne i przejrzyste, i nie mam żadnych skrupułów, by go użyć za każdym razem, gdy dykta jest mieszanką dwóch innych, które się przydaje (każdy czytelnik, który ma problemy ze zrozumieniem, będzie w rzeczywistości bardzo dobrze obsługiwany przez sposób, który skłania go do poznania formy dict i ** ;-). Tak więc, na przykład, zastosowania takie jak:

x = mungesomedict(dict(adict, **anotherdict)) 

są dość częste w moim kodzie.

Oryginalnie napisane przez Alex Martelli

Uwaga: W Pythonie 3, to będzie działać tylko wtedy, gdy każdy klucz w basket_two jest string.

+2

Dokumentacja dla ['dict' ] (http://docs.python.org/2/library/stdtypes.html#dict) jest łatwe do znalezienia podczas ['**'] (http://www.saltycrane.com/blog/2008/01/ how-to-use-args-and-kwargs-in-python /) jest nieco trudniejsze (słowo kluczowe to * kwargs *). Oto ładne wyjaśnienie: http://www.saltycrane.com/blog/2008/01/how-to-use-args-and-kwargs-in-python/ – johndodo

+1

może to być użyte do wygenerowania drugiej zmiennej o jedno polecenie, podczas gdy 'basket_one.update ()' jak wspomniano, aktualizuje istniejący słownik (lub sklonowany). – furins

+1

Należy zauważyć, że w Pythonie 3 nazwy argumentów, a tym samym klucze '** anotherdict', muszą być ciągami. –

15

Jak wspominają inni, a.update(b) dla niektórych dicts a i b osiągnie wynik masz hasła w swoim pytaniu. Jednakże chcę zauważyć, że wielokrotnie widziałem metodę mapowania/ustawiania obiektów, która wymaga, aby w wartościach składni NIE były nadpisywane wartościami b. a.update(b) zastępuje wartości a, więc nie jest dobrym wyborem dla extend.

Należy pamiętać, że niektóre języki nazywają tę metodę defaults lub inject, ponieważ można ją traktować jako sposób wstrzykiwania wartości b (które mogą być zestawem wartości domyślnych) do słownika bez nadpisywania wartości, które mogą już istnieć.

Oczywiście można łatwo zauważyć, że a.extend(b) jest prawie taki sam jak b.update(a); a=b.Aby usunąć zadanie, można to zrobić w następujący sposób:

def extend(a,b): 
    """Create a new dictionary with a's properties extended by b, 
    without overwriting. 

    >>> extend({'a':1,'b':2},{'b':3,'c':4}) 
    {'a': 1, 'c': 4, 'b': 2} 
    """ 
    return dict(b,**a) 

Dzięki Tom Leys dla tej idei inteligentnej za pomocą efektem ubocznym mniej dict konstruktora dla extend.

Powiązane problemy