Python'da veri yapısı olan dict, genellikle iç içe bilgiler saklamak için kullanılır. Geliştiriciler, şablonlar, konfigürasyonlar veya uygulama parçaları arasında veri aktarımı yaparken bu tür yapıların kopyalanması gerekliliğiyle sıkça karşılaşırlar.
Dict'in standart kopyalanması, atama (=) ile yalnızca orijinal nesneye bir referans oluşturur. Yüzeysel kopyalama (shallow copy) yalnızca dict nesnesinin kendisini kopyalar, ancak iç içe nesneleri kopyalamaz. Derin kopyalama (deep copy) ise içindeki tüm nesneleri özyinelemeli olarak kopyalar, bu da bir kopyadaki değişikliklerin diğerini etkilemesini engeller.
Yüzeysel kopyalama için dict.copy() veya dict() yapıcısını kullanabilirsiniz, derin kopyalamak için ise copy modülünü ve deepcopy() fonksiyonunu kullanmalısınız:
import copy d = {"a": 1, "b": {"c": 2}} shallow_d = d.copy() deep_d = copy.deepcopy(d) # Artık shallow_d['b']['c'] değişikliği d['b']['c']'yi etkiler # deep_d['b']['c'] değişikliği orijinal sözlüğü etkilemez
Anahtar özellikler:
dict.copy() ilk seviyenin altındaki sekmeleri kopyalayabilir mi?
Hayır, dict.copy() yalnızca yüzeysel bir kopya oluşturur. İç içe sözlükler yine de orijinal dict'teki nesnelerin referansları olacaktır.
Yapıda değişmez bir nesne (örneğin, tuple) varsa, deepcopy bu nesneyi derin bir şekilde kopyalar mı?
Deepcopy yalnızca değiştirilebilir iç nesneleri kopyalar. Değişmez nesneler aynı kalır — tuple'lar, dizeler ve sayılar özyinelemeli olarak kopyalanmaz, yalnızca kopyaya taşınır.
Derin kopyalama için json.loads(json.dumps(dict)) üzerinden seri hale getirme kullanılabilir mi?
Kullanılabilir, ancak bazı şartlar var. Bu yöntem yalnızca seri hale getirilebilir türler için çalışır ve sözlükte seri hale getirilemeyen nesneler varsa (örneğin, fonksiyonlar veya özel sınıflar) uygun değildir:
import json orig = {"a": 10, "b": [1,2,3]} copy_like_deep = json.loads(json.dumps(orig)) # Karmaşık nesneler için çalışmaz
** Olumsuz Durum
Geliştirici ayarları copy() ile klonlar ve sonra iç içe bir değeri değiştirir, iki bağımsız yapı olduğunu düşünerek.
Artıları:
Basit ve hızlı
Eksileri:
Bir kopyadaki iç nesnelerin değişiklikleri tüm kopyalara yansır — düzeltmesi zor hatalar.
** Olumlu Durum
Geliştirici, orijinal dict düz görünse bile her zaman copy.deepcopy() kullanır.
Artıları:
Verilerin bağımsızlığı garanti ediliyor, hatalar en aza indiriliyor.
Eksileri:
Deepcopy daha yavaş ve daha fazla bellek tüketir, bazen gereksizdir.