Na przykład mam dwa dyktanda:
Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}
Potrzebuję pytonowego sposobu „łączenia” dwóch dykt, tak aby wynik był następujący:
{'a': 1, 'b': 5, 'c': 7, 'd': 5}
To znaczy: jeśli klucz pojawia się w obu nagraniach, dodaj ich wartości, jeśli pojawia się tylko w jednym nagraniu, zachowaj jego wartość.
python
dictionary
Derrick Zhang
źródło
źródło
sum(counters)
nie działa niestety.sum()
wartość początkową za pomocąsum(counters, Counter())
.+=
sumowanie w miejscu.res = counters[0]
, A następniefor c in counters[1:]: res += c
.update()
zamiast+=
:for c in counters[1:]: res.update(c)
.Bardziej ogólne rozwiązanie, które działa również dla wartości nienumerycznych:
lub nawet bardziej ogólny:
Na przykład:
źródło
for k in b.viewkeys() & a.viewkeys()
, używając Pythona 2.7 , i pominąć tworzenie zestawów.set(a)
zwraca zestaw kluczy zamiast zestawu krotek? Jakie jest tego uzasadnienie?list({..})
,for k in {...}
itpoperator.mul
wyjaśniać, że ten kod jest ogólny i nie ogranicza się do dodawania liczb.{**a, **b, **{k: op(a[k], b[k]) for k in a.keys() & b}}
powinien działać w Python 3.5+.źródło
for x in set(itertools.chain(A, B))
byłoby bardziej logiczne? Czy używanie zestawu na dykcie jest trochę nonsensowne, ponieważ klucze są już unikalne? Wiem, że to tylko inny sposób na zdobycie zestawu kluczy, ale uważam, że jest to bardziej mylące niż używanieitertools.chain
(co oznacza, że wiesz, coitertools.chain
robi)Wprowadzenie: Istnieją (prawdopodobnie) najlepsze rozwiązania. Ale musisz to wiedzieć i pamiętać o tym, a czasem musisz mieć nadzieję, że twoja wersja Pythona nie jest zbyt stara lub jakikolwiek problem.
Są też najbardziej „hackerskie” rozwiązania. Są świetne i krótkie, ale czasem trudno je zrozumieć, przeczytać i zapamiętać.
Istnieje jednak alternatywa polegająca na ponownym wymyśleniu koła. - Po co wymyślać koło? - Zasadniczo dlatego, że jest to naprawdę dobry sposób na naukę (a czasami tylko dlatego, że już istniejące narzędzie nie robi dokładnie tego, co chcesz i / lub tak, jak chcesz) i najłatwiejszy, jeśli nie wiesz lub nie pamiętam idealnego narzędzia dla twojego problemu.
Tak , że proponuje nowo koło z
Counter
grupy zcollections
modułem (co najmniej częściowo)Prawdopodobnie istniałby inny sposób, aby to zaimplementować i istnieją już narzędzia do tego, ale zawsze miło jest wyobrazić sobie, jak rzeczy w zasadzie będą działać.
źródło
źródło
Ten bez dodatkowych importów!
Ich jest pythonowym standardem o nazwie EAFP (łatwiej prosić o przebaczenie niż pozwolenie). Poniższy kod oparty jest na tym standardzie Pythona .
EDYCJA: dzięki jerzyk za sugestie ulepszenia.
źródło
Zdecydowanie sumowanie
Counter()
s jest najbardziej pytoniczną drogą w takich przypadkach, ale tylko wtedy, gdy daje dodatnią wartość . Oto przykład i, jak widać, nie mac
rezultatu po zanegowaniuc
wartości wB
słowniku.Wynika to z faktu, że
Counter
s zostały zaprojektowane przede wszystkim do pracy z dodatnimi liczbami całkowitymi do reprezentowania liczby zliczeń (liczba ujemna jest bez znaczenia). Aby jednak pomóc w tych przypadkach użycia, Python dokumentuje minimalne ograniczenia zakresu i typów w następujący sposób:Aby ominąć ten problem po zsumowaniu licznika, możesz użyć go
Counter.update
, aby uzyskać pożądany efekt. Działa jak,dict.update()
ale dodaje liczby zamiast ich zastępowania.źródło
LUB
Alternatywnie możesz użyć Counter, jak wspomniano powyżej w @Martijn.
źródło
Aby uzyskać bardziej ogólny i rozszerzalny sposób, sprawdź scaledict . Wykorzystuje
singledispatch
i może łączyć wartości na podstawie swoich typów.Przykład:
źródło
Z Python 3.5: scalanie i sumowanie
Dzięki @tokeinizer_fsj, który powiedział mi w komentarzu, że nie do końca rozumiem znaczenie pytania (myślałem, że dodanie oznacza po prostu dodanie kluczy, które ostatecznie różnią się w dwóch słownikach, a zamiast tego miałem na myśli wspólne wartości klucza należy zsumować). Dodałem więc tę pętlę przed scaleniem, aby drugi słownik zawierał sumę wspólnych kluczy. Ostatni słownik będzie tym, którego wartości będą trwać w nowym słowniku, który jest wynikiem połączenia dwóch, więc myślę, że problem został rozwiązany. Rozwiązanie jest poprawne z Pythona 3.5 i kolejnych wersji.
Kod wielokrotnego użytku
źródło
b
to5
(2 + 3), ale twoja metoda powraca3
.Dodatkowo należy pamiętać, że
a.update( b )
jest 2x szybszy niża + b
źródło
Możesz łatwo to uogólnić:
Może to zająć dowolną liczbę dykt.
źródło
Jest to proste rozwiązanie do łączenia dwóch słowników, w których
+=
można zastosować wartości, musi iterować słownik tylko razźródło
To rozwiązanie jest łatwe w użyciu, jest używane jako zwykły słownik, ale można użyć funkcji sumowania.
źródło
Co powiesz na:
Wynik:
źródło
Powyższe rozwiązania są idealne dla scenariusza, w którym masz niewielką liczbę
Counter
s. Jeśli masz ich dużą listę, coś takiego jest o wiele ładniejsze:Powyższe rozwiązanie zasadniczo podsumowuje
Counter
s poprzez:Robi to samo, ale myślę, że zawsze pomaga zobaczyć, co skutecznie robi pod spodem.
źródło
Scalenie trzech dykt a, b, c w jednej linii bez żadnych innych modułów lub bibliotek
Jeśli mamy trzy dyktanda
Scal wszystko za pomocą jednej linii i zwróć obiekt dict za pomocą
Powracający
źródło
{'a': 9, 'b': 9, 'd': 90}
. Brakuje wymogu „suma”.