Apakah ada cara untuk memiliki defaultdict(defaultdict(int))
agar kode berikut berfungsi?
for x in stuff:
d[x.a][x.b] += x.c_int
d
perlu dibangun ad-hoc, tergantung pada x.a
dan x.b
elemen.
Saya bisa menggunakan:
for x in stuff:
d[x.a,x.b] += x.c_int
tapi kemudian saya tidak bisa menggunakan:
d.keys()
d[x.a].keys()
python
collections
Jonathan
sumber
sumber
Jawaban:
Ya seperti ini:
Argumen a
defaultdict
(dalam hal ini adalahlambda: defaultdict(int)
) akan dipanggil ketika Anda mencoba mengakses kunci yang tidak ada. Nilai pengembaliannya akan ditetapkan sebagai nilai baru dari kunci ini, yang berarti dalam kasus kami nilaid[Key_doesnt_exist]
akandefaultdict(int)
.Jika Anda mencoba mengakses kunci dari default default terakhir ini yaitu
d[Key_doesnt_exist][Key_doesnt_exist]
akan mengembalikan 0, yang merupakan nilai pengembalian argumen dari default default yaituint()
.sumber
defaultdict
(dalam hal inilambda : defaultdict(int)
) akan dipanggil ketika Anda mencoba mengakses kunci yang tidak ada dan nilai pengembaliannya akan ditetapkan sebagai nilai baru dari kunci ini yang berarti dalam kasus kami nilaid[Key_dont_exist]
akandefaultdict(int)
, dan jika Anda mencoba mengakses kunci dari defaultdict terakhir ini yaitud[Key_dont_exist][Key_dont_exist]
akan mengembalikan 0 yang merupakan nilai pengembalian argumen terakhirdefaultdict
yaituint()
, Semoga ini bermanfaat.defaultdict
menjadi fungsi.defaultdict(int)
adalah kamus, sedangkanlambda: defaultdict(int)
fungsi yang mengembalikan kamus.defaultdict(lambda: defaultdict(lambda: defaultdict(int)))
Parameter ke konstruktor defaultdict adalah fungsi yang akan dipanggil untuk membangun elemen baru. Jadi mari kita gunakan lambda!
Sejak Python 2.7, ada solusi yang lebih baik lagi menggunakan Counter :
Beberapa fitur bonus
Untuk informasi lebih lanjut lihat PyMOTW - Koleksi - tipe data wadah dan Dokumentasi Python - koleksi
sumber
d = defaultdict(lambda : Counter())
daripadad = defaultdict(lambda : defaultdict(int))
untuk secara khusus mengatasi masalah seperti yang diajukan sebelumnya.d = defaultdict(Counter())
tidak perlu untuk lambda dalam kasus iniCounter
objek. Itu adalah:d = defaultdict(Counter)
Saya merasa sedikit lebih elegan untuk digunakan
partial
:Tentu saja, ini sama dengan lambda.
sumber
Untuk referensi, dimungkinkan untuk menerapkan
defaultdict
metode pabrik bersarang generik melalui:Kedalaman menentukan jumlah kamus bersarang sebelum jenis yang didefinisikan
default_factory
digunakan. Sebagai contoh:sumber
ndd = nested_defaultdict(dict) .... ndd['a']['b']['c']['d'] = 'e'
throwsKeyError: 'b'
depth=0
, yang mungkin tidak selalu diinginkan jika kedalamannya tidak diketahui pada saat menelepon. Mudah diperbaiki dengan menambahkan garisif not depth: return default_factory()
, di bagian atas fungsi, meskipun mungkin ada solusi yang lebih elegan.Jawaban sebelumnya telah membahas cara membuat dua level atau n-level
defaultdict
. Dalam beberapa kasus Anda ingin yang tak terbatas:Pemakaian:
sumber
Orang lain telah menjawab dengan benar pertanyaan Anda tentang cara membuat yang berikut ini berfungsi:
Alternatifnya adalah menggunakan tuple untuk kunci:
Hal yang menyenangkan tentang pendekatan ini adalah sederhana dan dapat dengan mudah diperluas. Jika Anda membutuhkan pemetaan tiga level, gunakan tuple tiga item untuk kunci tersebut.
sumber