Python”da hash(dictionary)“lerle çalışırken bir değer dict içinde değilse ona önceden tanımlı bir değer vermemiz gerekebilir. Örneğin bir yazı içeresinde geçen sözcüklerin kaç defa tekrarlandığını bulmak istiyorsak, şöyle birşey yaparız :
1 2 3 4 5 6 |
|
Bunun yerine şöyle birşey yapabiliyor olsak daha güzel olurdu :
1
|
|
İşte bu tür bir kullanımı mümkün kılan defaultdict var :
1
|
|
Önceki örneği defaultdict ile yaparsak şöyle birşey olur :
1 2 3 4 5 |
|
defaultdict aynen normal bir dictionary gibi davranıyor. Fakat, ondan farklı olarak bir değeri alırken eğer o değer dictionary içeresinde yoksa, ona baştan verdiğimiz fonksyonu çağırıp ondan dönen değeri set ediyor.
Nasıl mı ? Örnek verecek olursak :
1 2 3 4 5 6 7 8 9 10 |
|
Burada defaultdict”e ilk parametre olarak lambda verdik ve içeresinde olmayan bir değer istendiğinde bize “missing_value” değerini döndürdü.
defaultdict”in koduna bakmadım, ama büyük ihtimalle şöyle birşey yapıyordur.
Bir müşteri için çalıştığım bir projede bir ayar dosyasını(json) okuyup normal bir objeymiş gibi erişmek istiyordum. Örnek olarak :
1 2 3 4 5 6 7 |
|
Gibi bir Python dictionary olsun ve biz buna normal bir objeymiş gibi erişebillim, şöyle ki :
1 2 |
|
Bu tür bir kullanımı mümkün kılmak için defaultdict kullanıp __setattr__ ve __getattr__ fonksyonlarını ezdim(override) :
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Sadece bu şekilde kullanırsak pek işimize yaramayacak çünkü iç içe girmiş
yapılara erişim sağalayamacak. Yani bir değer bulunamadığında tekrar
DefDict objesi döndürmemiz gerekir. Şöyle:
1 2 |
|
Fonksyon recursive, yani her değer bulamayışında bulamadığı değere DefDict objesi atayacak.(Başta bakınca biraz karışık görünüyor, ama biraz zaman verin gözünüz alışacaktır.)
Şimdi bu yapıyı bu şekilde kullanabiliriz :
1 2 3 4 5 6 7 8 9 10 11 |
|
Gerçekten kullanım olarak çok kolaylık sağlıyor, ayrıca isterseniz normal dictionary gibi de kullanmaya devam edebilirsiniz.
Bu tür bir yapının şöyle bir de dezavantajı var. Her bulamadığı değer için yeni bir DefDict yapısı oluşturduğu için, siz bulunamayan bu değere atama yapmasanız da o alt tarafta oluşturuluyor :
1 2 3 4 5 6 7 8 9 10 11 |
|
Bu sorunu çözmeyi başaramadım, bulan varsa lütfen yorumlara yazsın.