ProgramlamaBackend geliştirici

Dict'te shallow ve deep copy arasındaki fark nedir ve Python'da iç içe sözlükleri nasıl doğru bir şekilde kopyalarsınız?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Soru Tarihi

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.

Problemi

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.

Çözüm

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:

  • Yüzeysel kopyalama yalnızca nesnenin "dış kabuğunu" kopyalar
  • Derin kopyalama, yapı içindeki tüm nesneleri özyinelemeli olarak kopyalar
  • İç içe yapıların çalışmasında, kopyanın tam bağımsızlığını sağlamak için her zaman deepcopy kullanın

Kandırmaca Sorular.

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

Tipik Hatalar ve Anti-Desenler

  • Kopyalama yerine basit atama kullanmak
  • İç içe yapılara yüzeysel kopyalama uygulamak, bu da tüm "kopyalarda" beklenmedik değişikliklere yol açar.

Gerçek Hayattan Bir Örnek

** 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.