d3 = dict(d1, **d2)
Saya mengerti bahwa ini menggabungkan kamus. Tapi, apakah itu unik? Bagaimana jika d1 memiliki kunci yang sama dengan d2 tetapi nilainya berbeda? Saya ingin d1 dan d2 digabungkan, tetapi d1 memiliki prioritas jika ada kunci duplikat.
python
dictionary
TIMEX
sumber
sumber
**
argumen kata kunci yang lewat kecuali semua kuncid2
adalah string. Jika tidak semua kuncid2
adalah string, ini gagal di Python 3.2, dan dalam implementasi alternatif Python seperti Jython, IronPython, dan PyPy. Lihat, misalnya, mail.python.org/pipermail/python-dev/2010-April/099459.html .Jawaban:
Anda dapat menggunakan
.update()
metode ini jika Anda tidak membutuhkan yang aslid2
lagi:Misalnya:
>>> d1 = {'a': 1, 'b': 2} >>> d2 = {'b': 1, 'c': 3} >>> d2.update(d1) >>> d2 {'a': 1, 'c': 3, 'b': 2}
Memperbarui:
Tentu saja Anda dapat menyalin kamus terlebih dahulu untuk membuat yang baru digabungkan. Ini mungkin atau mungkin tidak perlu. Jika Anda memiliki objek gabungan (objek yang berisi objek lain, seperti daftar atau instance kelas) dalam kamus Anda,
copy.deepcopy
juga harus dipertimbangkan.sumber
isinstance(int, object) is True
namundeepcopy
sepertinya tidak perlu.Di Python2,
d1={'a':1,'b':2} d2={'a':10,'c':3}
d1 menggantikan d2:
dict(d2,**d1) # {'a': 1, 'c': 3, 'b': 2}
d2 menggantikan d1:
dict(d1,**d2) # {'a': 10, 'c': 3, 'b': 2}
Perilaku ini bukan hanya kebetulan implementasi; itu dijamin dalam dokumentasi :
sumber
**
notasi, semua kunci dari dict itu harus berupa string. Lihat utas python-dev mulai dari mail.python.org/pipermail/python-dev/2010-April/099427.html untuk selengkapnya.d = dict(**d1, **d2)
berhasil, tetapi itulah yang dirujuk @IoannisFilippidis dalam komentar mereka. Mungkin menyertakan cuplikan di sini akan lebih jelas, jadi ini dia.Jika Anda ingin
d1
mendapat prioritas dalam konflik, lakukan:Jika tidak, balikkan
d2
dand1
.sumber
Solusi saya adalah menentukan fungsi penggabungan . Itu tidak canggih dan hanya membutuhkan biaya satu baris. Berikut kode di Python 3.
from functools import reduce from operator import or_ def merge(*dicts): return { k: reduce(lambda d, x: x.get(k, d), dicts, None) for k in reduce(or_, map(lambda x: x.keys(), dicts), set()) }
Tes
>>> d = {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} >>> d_letters = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'} >>> merge(d, d_letters) {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'} >>> merge(d_letters, d) {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'} >>> merge(d) {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} >>> merge(d_letters) {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z', 26: 'A', 27: 'B', 28: 'C', 29: 'D', 30: 'E', 31: 'F', 32: 'G', 33: 'H', 34: 'I', 35: 'J', 36: 'K', 37: 'L', 38: 'M', 39: 'N', 40: 'O', 41: 'P', 42: 'Q', 43: 'R', 44: 'S', 45: 'T', 46: 'U', 47: 'V', 48: 'W', 49: 'X', 50: 'Y', 51: 'Z'} >>> merge() {}
Ia bekerja untuk sejumlah argumen kamus. Jika ada kunci duplikat dalam kamus tersebut, kunci dari kamus paling kanan dalam daftar argumen menang.
sumber
.update
panggilan di dalamnya (merged={}
diikuti olehfor d in dict: merged.update(d)
) akan lebih pendek, lebih mudah dibaca dan lebih efisien.reduce
danlambda
, bagaimanareturn reduce(lambda x, y: x.update(y) or x, dicts, {})
?Trey Hunner memiliki entri blog yang bagus yang menguraikan beberapa opsi untuk menggabungkan beberapa kamus, termasuk (untuk python3.3 +) ChainMap dan pembongkaran kamus .
sumber
Dimulai
Python 3.9
, operator|
membuat kamus baru dengan kunci dan nilai yang digabungkan dari dua kamus:# d1 = { 'a': 1, 'b': 2 } # d2 = { 'b': 1, 'c': 3 } d3 = d2 | d1 # d3: {'b': 2, 'c': 3, 'a': 1}
Ini:
Perhatikan juga
|=
operator yang mengubah d2 dengan menggabungkan d1 in, dengan prioritas pada nilai d1:# d1 = { 'a': 1, 'b': 2 } # d2 = { 'b': 1, 'c': 3 } d2 |= d1 # d2: {'b': 2, 'c': 3, 'a': 1}
sumber
Saya percaya bahwa, seperti yang dinyatakan di atas, menggunakan
d2.update(d1)
adalah pendekatan terbaik dan Anda juga dapat menyalinnyad2
terlebih dahulu jika masih membutuhkannya.Meskipun, saya ingin menunjukkan bahwa
dict(d1, **d2)
sebenarnya cara yang buruk untuk menggabungkan kamus secara umum karena argumen kata kunci harus berupa string, sehingga akan gagal jika Anda memilikidict
seperti:{ 1: 'foo', 2: 'bar' }
sumber