Berkat beberapa orang hebat di SO, saya menemukan kemungkinan yang ditawarkan oleh collections.defaultdict
, terutama dalam keterbacaan dan kecepatan. Saya telah menggunakan mereka dengan sukses.
Sekarang saya ingin mengimplementasikan tiga tingkat kamus, dua yang teratas defaultdict
dan yang paling rendah int
. Saya tidak menemukan cara yang tepat untuk melakukan ini. Ini usaha saya:
from collections import defaultdict
d = defaultdict(defaultdict)
a = [("key1", {"a1":22, "a2":33}),
("key2", {"a1":32, "a2":55}),
("key3", {"a1":43, "a2":44})]
for i in a:
d[i[0]] = i[1]
Sekarang ini berfungsi, tetapi yang berikut, yang merupakan perilaku yang diinginkan, tidak:
d["key4"]["a1"] + 1
Saya menduga bahwa saya seharusnya menyatakan di suatu tempat bahwa tingkat kedua defaultdict
adalah tipe int
, tetapi saya tidak menemukan di mana atau bagaimana melakukannya.
Alasan saya menggunakan defaultdict
di tempat pertama adalah untuk menghindari keharusan menginisialisasi kamus untuk setiap kunci baru.
Ada saran yang lebih elegan?
Terima kasih pythoneers!
sumber
multiprocessing
tidak senang mengirim ini bolak-balik.d[new_key]
diakses, itu akan memanggil lambda yang akan membuat yang barudefaultdict(int)
. Dan ketikad[existing_key][new_key2]
diakses, baruint
akan dibuat.multiprocessing
dan apa fungsi tingkat modul bernama itu? Pertanyaan ini menindaklanjuti.Cara lain untuk membuat pickleable, nested defaultdict adalah dengan menggunakan objek parsial alih-alih lambda:
Ini akan berfungsi karena kelas defaultdict dapat diakses secara global di tingkat modul:
sumber
Lihatlah jawaban nosklo di sini untuk solusi yang lebih umum.
Pengujian:
Keluaran:
sumber
Sesuai permintaan @ rschwieb untuk
D['key'] += 1
, kami dapat memperluas sebelumnya dengan mengesampingkan penambahan dengan mendefinisikan__add__
metode, untuk membuat ini berperilaku lebih seperticollections.Counter()
Pertama
__missing__
akan dipanggil untuk membuat nilai kosong baru, yang akan diteruskan__add__
. Kami menguji nilainya, mengandalkan nilai kosong menjadiFalse
.Lihat mengemulasi tipe numerik untuk informasi lebih lanjut tentang mengganti.
Contoh:
Daripada memeriksa argumen adalah Angka (sangat non-python, amirite!) Kita bisa memberikan nilai 0 default dan kemudian mencoba operasi:
sumber
Terlambat ke pesta, tapi untuk kedalaman yang sewenang-wenang, aku baru saja melakukan sesuatu seperti ini:
Triknya di sini adalah membuat
DeepDict
instance itu sendiri sebagai pabrik yang valid untuk membangun nilai yang hilang. Sekarang kita bisa melakukan hal-hal sepertisumber
Tidak ada kesalahan lagi. Tidak peduli berapa banyak level yang bersarang. pop no error juga
dd = DefaultDict ({"1": 333333})
sumber