Misalnya saya punya dua dicts:
Dict A: {'a': 1, 'b': 2, 'c': 3}
Dict B: {'b': 3, 'c': 4, 'd': 5}
Saya membutuhkan cara pythonic untuk 'menggabungkan' dua dicts sehingga hasilnya adalah:
{'a': 1, 'b': 5, 'c': 7, 'd': 5}
Dengan kata lain: jika sebuah kunci muncul di kedua dicts, tambahkan nilainya, jika hanya muncul dalam satu dict, pertahankan nilainya.
python
dictionary
Derrick Zhang
sumber
sumber
sum(counters)
sayangnya tidak bekerja.sum()
nilai awal, dengansum(counters, Counter())
.+=
melakukan penjumlahan di tempat.res = counters[0]
, Kemudianfor c in counters[1:]: res += c
.update()
bukan+=
:for c in counters[1:]: res.update(c)
.Solusi yang lebih umum, yang juga berfungsi untuk nilai-nilai non-numerik:
atau bahkan lebih umum:
Sebagai contoh:
sumber
for k in b.viewkeys() & a.viewkeys()
, ketika menggunakan python 2.7 , dan melewati pembuatan set.set(a)
mengembalikan set kunci daripada set tupel? Apa alasannya?list({..})
,for k in {...}
dlloperator.mul
menjelaskan bahwa kode ini generik dan tidak terbatas pada penambahan angka.{**a, **b, **{k: op(a[k], b[k]) for k in a.keys() & b}}
harus bekerja dengan Python 3.5+.sumber
for x in set(itertools.chain(A, B))
lebih logis? Seperti menggunakan set pada dikt adalah sedikit omong kosong karena kunci sudah unik? Saya tahu ini hanyalah cara lain untuk mendapatkan satu set kunci tetapi saya merasa lebih membingungkan daripada menggunakanitertools.chain
(menyiratkan Anda tahu apa yang harusitertools.chain
dilakukan)Intro: Ada (mungkin) solusi terbaik. Tetapi Anda harus mengetahuinya dan mengingatnya dan kadang-kadang Anda harus berharap bahwa versi Python Anda tidak terlalu tua atau apa pun masalahnya.
Lalu ada solusi yang paling 'retas'. Mereka hebat dan pendek tetapi kadang-kadang sulit dimengerti, dibaca dan diingat.
Namun, ada alternatif untuk mencoba menemukan kembali roda. - Mengapa menciptakan kembali roda? - Umumnya karena ini adalah cara yang sangat baik untuk belajar (dan kadang-kadang hanya karena alat yang sudah ada tidak melakukan apa yang Anda inginkan dan / atau cara Anda suka) dan cara termudah jika Anda tidak tahu atau jangan ingat alat yang sempurna untuk masalah Anda.
Jadi , saya mengusulkan untuk menemukan kembali roda
Counter
kelas daricollections
modul (setidaknya sebagian):Mungkin akan ada cara lain untuk mengimplementasikannya dan sudah ada alat untuk melakukan itu tetapi selalu menyenangkan untuk memvisualisasikan bagaimana hal-hal pada dasarnya akan bekerja.
sumber
sumber
Yang tanpa impor tambahan!
Mereka adalah standar pythonic yang disebut EAFP (Lebih Mudah Meminta Pengampunan daripada Izin). Kode di bawah ini didasarkan pada standar python itu .
EDIT: terima kasih kepada jerzyk untuk saran peningkatannya.
sumber
Menjumlahkan
Counter()
s adalah cara yang paling pythonic dalam kasus-kasus seperti itu tetapi hanya jika menghasilkan nilai positif . Berikut ini adalah contoh dan seperti yang Anda lihat tidak adac
hasil setelah meniadakanc
nilai dalamB
kamus.Itu karena
Counter
s terutama dirancang untuk bekerja dengan bilangan bulat positif untuk mewakili jumlah berjalan (jumlah negatif tidak ada artinya). Tetapi untuk membantu kasus penggunaan tersebut, python mendokumentasikan kisaran minimum dan jenis pembatasan sebagai berikut:Jadi untuk mengatasi masalah itu setelah menjumlahkan Counter Anda, Anda dapat menggunakan
Counter.update
untuk mendapatkan output keinginan. Ini berfungsi sepertidict.update()
tetapi menambahkan jumlah alih-alih menggantinya.sumber
ATAU
Alternatif Anda dapat menggunakan Penghitung seperti @Martijn telah disebutkan di atas.
sumber
Untuk cara yang lebih umum dan dapat diperluas, periksa mergedict . Ini menggunakan
singledispatch
dan dapat menggabungkan nilai berdasarkan jenisnya.Contoh:
sumber
Dari python 3.5: penggabungan dan penjumlahan
Terima kasih kepada @tokeinizer_fsj yang memberi tahu saya dalam komentar bahwa saya tidak sepenuhnya memahami arti dari pertanyaan tersebut (saya pikir bahwa menambahkan berarti hanya menambahkan kunci yang pada akhirnya berbeda di kedua dictinaries dan, sebaliknya, saya maksudkan bahwa nilai-nilai kunci umum harus dijumlahkan). Jadi saya menambahkan loop itu sebelum penggabungan, sehingga kamus kedua berisi jumlah dari tombol-tombol umum. Kamus terakhir adalah kamus yang nilainya akan bertahan di kamus baru yang merupakan hasil penggabungan keduanya, jadi saya pikir masalahnya sudah terpecahkan. Solusinya valid dari python 3.5 dan versi berikut.
Kode yang dapat digunakan kembali
sumber
b
adalah5
(2 + 3), tetapi metode Anda kembali3
.Selain itu, harap dicatat
a.update( b )
2x lebih cepat daria + b
sumber
Anda dapat dengan mudah menggeneralisasi ini:
Kemudian dapat mengambil sejumlah dikte.
sumber
Ini adalah solusi sederhana untuk menggabungkan dua kamus di mana
+=
dapat diterapkan ke nilai-nilai, itu harus beralih ke kamus hanya sekalisumber
Solusi ini mudah digunakan, digunakan sebagai kamus normal, tetapi Anda dapat menggunakan fungsi penjumlahan.
sumber
Bagaimana dengan:
Keluaran:
sumber
Solusi di atas sangat bagus untuk skenario di mana Anda memiliki sejumlah kecil
Counter
. Jika Anda memiliki daftar besar mereka, sesuatu seperti ini jauh lebih baik:Solusi di atas pada dasarnya menjumlahkan
Counter
s dengan:Ini melakukan hal yang sama tetapi saya pikir itu selalu membantu untuk melihat apa yang dilakukannya secara efektif di bawahnya.
sumber
Menggabungkan tiga dict a, b, c dalam satu baris tanpa modul atau lib lainnya
Jika kita memiliki tiga dicts
Gabungkan semua dengan satu baris dan kembalikan objek dict menggunakan
Kembali
sumber
{'a': 9, 'b': 9, 'd': 90}
. Anda kehilangan persyaratan "jumlah".