Bir sözlük nasıl kopyalanır ve yalnızca kopya nasıl düzenlenir


855

Lütfen biri bunu bana açıklayabilir mi? Bu benim için bir anlam ifade etmiyor.

Bir sözlüğü diğerine kopyalarım ve ikinciyi düzenlerim ve her ikisi de değişir. Bu neden oluyor?

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict1
>>> dict2
{'key2': 'value2', 'key1': 'value1'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key2': 'WHY?!', 'key1': 'value1'}

4
PythonTutor Python referanslarını görselleştirmek için mükemmeldir. İşte son adımda bu kod . Aynı dikteyi görebilir dict1ve gösterebilirsiniz dict2.
wjandrea

Yanıtlar:


883

Python nesneleri dolaylı olarak hiçbir zaman kopyalamaz. Ayarladığınızda dict2 = dict1, onları aynı tam dikte nesnesine gönderme yapıyor olursunuz, bu nedenle onu değiştirdiğinizde, ona yapılan tüm referanslar, mevcut durumdaki nesneye başvurmaya devam eder.

Eğer dikteyi kopyalamak istiyorsanız (ki bu nadirdir), bunu açıkça

dict2 = dict(dict1)

veya

dict2 = dict1.copy()

26
"Dict2 ve dict1 aynı sözlüğe işaret" demek daha iyi olabilir , dict1 veya dict2'yi değiştirmiyorsunuz ama neyi işaret ediyorsunuz.
GrayWizardx

276
Ayrıca, dict.copy () 'nin sığ olduğunu, iç içe bir liste / vb. Varsa, her ikisine de değişiklikler uygulanacağını unutmayın. IIRC. Deepcopy bundan kaçınacaktır.
Will

16
Python'un nesneleri örtük olarak asla kopyalamaması tam olarak doğru değildir. İnt, float ve bool gibi ilkel veri türleri de nesne olarak kabul edilir (bunu dir(1)görmek için sadece a yapın), ancak örtük olarak kopyalanırlar.
daniel kullmann

17
@danielkullmann, sanırım Python ile ilgili diğer dillerin nasıl çalıştığına bağlı olarak yanlış anlamalar yaşayabilirsiniz. Python'da, a) "İlkel veri türleri" kavramı yoktur. int, floatve boolörnekleri gerçek Python nesneleridir ve b) bu ​​tür nesneler, bunları ilettiğinizde dolaylı olarak semantik bir Python düzeyinde değil, CPython'da bir uygulama ayrıntısı olarak bile örtük olarak kopyalanmaz.
Mike Graham

39
"Derin kopya zararlı olarak kabul edilir" gibi kanıtlanmamış söylemler yararsızdır. Diğer her şey eşit olduğunda, karmaşık bir veri yapısının sığ kopyalanması, aynı yapının derin kopyalanmasından çok beklenmedik uç durumu sorunları üretme olasılığından önemli ölçüde daha yüksektir. Değişikliklerin orijinal nesneyi değiştirdiği bir kopya bir kopya değildir; bu bir böcek. Ergo, en kullanım durumları kesinlikle olmalıdır diyoruz copy.deepcopy()yerine dict()ya dict.copy(). İmran 'ın özlü cevap bu cevap aksine aklı sağ tarafındadır.
Cecil Curry

647

Atadığınızda dict2 = dict1, bir kopyasını oluşturmuyorsunuz dict1, bu dict2sadece başka bir adla sonuçlanıyor dict1.

Sözlükler, kullanım gibi değişken türlerini kopyalamak için copy/ deepcopyiçinde copymodül.

import copy

dict2 = copy.deepcopy(dict1)

80
Şimdiye kadar çalıştığım herhangi bir sözlük için, derin kopyaya ihtiyacım var ... Bir hata nedeniyle birkaç saat kaybettim çünkü iç içe bir sözlüğün tam bir kopyasını alamıyordum ve iç içe girişlerdeki değişikliklerim orijinali etkiliyordu .
flutefreak7

7
Burada aynı. deepcopy () hile yapar. Orijinal etkinliğin bir 'kopyasına' zaman damgası ekleyerek dönen bir önbellek içindeki içiçe dikmelerimi karıştırıyordu. Teşekkür ederim!
fxstein

8
Bu aslında doğru cevap olarak işaretlenmelidir; Bu cevap geneldir ve sözlükler sözlüğü için de geçerlidir.
orezvani

30
Bu kabul edilen cevap olmalı. Mevcut kabul edilen cevabın yorum bölümünde yer alan asılsız "Derin kopya zararlı kabul edilir" retorik, iç içe sözlükleri (burada belgelenenler gibi) kopyalarken senkronizasyon sıkıntılarını açıkça davet eder ve bu şekilde sorgulanmalıdır.
Cecil Curry

deepcopy karmaşık bir sözlük yapısında ilerlemenin yoludur. dict1.copy (), anahtarların değerlerini nesne olarak değil referans olarak kopyalar.
Rohith N

182

İken dict.copy()ve dict(dict1)bir kopyasını üretir, bunlar sadece sığ kopyaları. Derin bir kopya istiyorsanız copy.deepcopy(dict1), gereklidir. Bir örnek:

>>> source = {'a': 1, 'b': {'m': 4, 'n': 5, 'o': 6}, 'c': 3}
>>> copy1 = x.copy()
>>> copy2 = dict(x)
>>> import copy
>>> copy3 = copy.deepcopy(x)
>>> source['a'] = 10  # a change to first-level properties won't affect copies
>>> source
{'a': 10, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> copy3
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}
>>> source['b']['m'] = 40  # a change to deep properties WILL affect shallow copies 'b.m' property
>>> source
{'a': 10, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy1
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy2
{'a': 1, 'c': 3, 'b': {'m': 40, 'o': 6, 'n': 5}}
>>> copy3  # Deep copy's 'b.m' property is unaffected
{'a': 1, 'c': 3, 'b': {'m': 4, 'o': 6, 'n': 5}}

Python copymodül belgelerinden sığ ve derin kopyalar hakkında :

Sığ ve derin kopyalama arasındaki fark yalnızca bileşik nesnelerle (listeler veya sınıf örnekleri gibi başka nesneler içeren nesneler) ilgilidir:

  • Sığ bir kopya yeni bir bileşik nesne oluşturur ve daha sonra (mümkün olduğu ölçüde) orijinalinde bulunan nesnelere referanslar ekler.
  • Derin bir kopya yeni bir bileşik nesne oluşturur ve daha sonra, yinelemeli olarak, orijinalde bulunan nesnelerin içine kopyalar ekler.

2
bu, açıkça dikte üzerinde döngü oluşturmayacağı ve diğer birincil yapılar için kullanılabileceği için doğru cevap olmalıdır.
Nikkolasg

27
Sadece açıklığa kavuşturmak w=copy.deepcopy(x)için kilit nokta.
alcoholiday

Arasındaki fark nedir dict2 = dict1ve dict2 = copy.deepcopy(dict1)?
TheTank

1
@TheTank, y = x, iki adın (başvuruların) aynı nesneye başvurmasını sağlar, yani "y, x" doğrudur. Nesne üzerinde x ile yapılan herhangi bir değişiklik y ile aynı değişikliğe eşittir. Ancak u, v, w, örnekleme sırasında x'den kopyalanan değerlere sahip yeni farklı nesnelere referanstır. U, v (sığ kopya) ve w ( derin
gpanda

63

Python 3.5+ üzerinde, paketinden çıkarma operatörünü kullanarak sığ bir kopya elde etmenin daha kolay bir yolu vardır. Pep 448 tarafından tanımlanmıştır .

>>>dict1 = {"key1": "value1", "key2": "value2"}
>>>dict2 = {**dict1}
>>>print(dict2)
{'key1': 'value1', 'key2': 'value2'}
>>>dict2["key2"] = "WHY?!"
>>>print(dict1)
{'key1': 'value1', 'key2': 'value2'}
>>>print(dict2)
{'key1': 'value1', 'key2': 'WHY?!'}

** sözlüğü daha sonra dict2 öğesine atanan yeni bir sözlükte paketinden çıkarır.

Ayrıca her sözlüğün farklı bir kimliği olduğunu da doğrulayabiliriz.

>>>id(dict1)
 178192816

>>>id(dict2)
 178192600

Derin bir kopya gerekiyorsa, copy.deepcopy () hala yoludur.


3
Bu C ++ işaretçiler gibi korkunç görünüyor. Görevi gerçekleştirmek için güzel, ama okunabilirlik akıllıca bu tür operatörlerden hoşlanmıyorum.
Ernesto

1
Bir tür kurnaz görünümü var ... ama birden fazla sözlükleri birleştirirken sözdizimi oldukça düzgün görünüyor.
PabTorre

2
Buna dikkat edin, sadece sığ bir kopya gerçekleştirir.
Sebastian Dressler

haklısın @SebastianDressler, ayarlamalar yapacağım. thnx.
PabTorre

2
Bazı spicies ile kopya oluşturmak istiyorsanız dict2 = {**dict1, 'key3':'value3'}
kullanışlıdır

47

Hem Python 2.7 hem de 3'te bir diktenin kopyasını oluşturmanın en iyi ve en kolay yolları ...

Basit (tek düzey) sözlüğün bir kopyasını oluşturmak için:

1. Varolan diktüyü işaret eden bir referans oluşturmak yerine dict () yöntemini kullanarak .

my_dict1 = dict()
my_dict1["message"] = "Hello Python"
print(my_dict1)  # {'message':'Hello Python'}

my_dict2 = dict(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

2. Python sözlüğünün yerleşik update () yöntemini kullanarak.

my_dict2 = dict()
my_dict2.update(my_dict1)
print(my_dict2)  # {'message':'Hello Python'}

# Made changes in my_dict1 
my_dict1["name"] = "Emrit"
print(my_dict1)  # {'message':'Hello Python', 'name' : 'Emrit'}
print(my_dict2)  # {'message':'Hello Python'}

İç içe veya karmaşık sözlüğün bir kopyasını oluşturmak için:

Genel sığ ve derin kopyalama işlemleri sağlayan yerleşik kopyalama modülünü kullanın . Bu modül hem Python 2.7 hem de 3 sürümlerinde bulunur. *

import copy

my_dict2 = copy.deepcopy(my_dict1)

6
dict()Derin bir kopya değil, sığ bir kopya oluşturduğuna inanıyorum . Yani iç içe geçmişseniz dictdış dictkısım bir kopya olacaktır ancak iç diksiyon orijinal iç diksiyona bir referans olacaktır.
shmuels

@ shmuels evet, bu yöntemlerin her ikisi de derin değil, sığ bir kopya oluşturur. Bkz. Güncellenmiş cevap.
AKay Nirala

37

Ayrıca sözlük anlama ile yeni bir sözlük yapabilirsiniz. Bu, kopyaların içe aktarılmasını önler.

dout = dict((k,v) for k,v in mydict.items())

Tabii ki python> = 2.7'de şunları yapabilirsiniz:

dout = {k:v for k,v in mydict.items()}

Ancak geriye dönük uyumluluk için en iyi yöntem daha iyidir.


4
Bu, tam olarak nasıl ve neyin kopyalanacağı konusunda daha fazla kontrol sahibi olmak istiyorsanız özellikle yararlıdır. +1
Yaklaşan

14
Bu yöntemin derin bir kopya gerçekleştirmediğini ve kopyalanacak tuşları denetlemenize gerek olmayan sığ bir kopya istiyorsanız, d2 = dict.copy(d1)herhangi bir içe aktarma gerektirmediğini unutmayın.
Jarek Piórkowski

1
@ JarekPiórkowski: ya da bir yöntem gibi bir yöntemi çağırabilirsiniz:d2 = d1.copy()
Azat Ibrakov

İlk örnekte kavramaya ihtiyacınız olmadığını unutmayın. dict.itemszaten yinelenebilir bir anahtar / değer çifti döndürür. Böylece sadece kullanabilirsiniz dict(mydict.items())(sadece kullanabilirsiniz dict(mydict)). Girişleri filtrelemek istiyorsanız, bilgi sahibi olmanız faydalı olabilir.
Paul Rooney

22

Diğer sağlanan çözümlere ek olarak, **sözlüğü boş bir sözlüğe entegre etmek için kullanabilirsiniz , örn.

shallow_copy_of_other_dict = {**other_dict}.

Şimdi bir "sığ" kopyasına sahip olacaksınız other_dict.

Örneğinize uygulanır:

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = {**dict1}
>>> dict2
{'key1': 'value1', 'key2': 'value2'}
>>> dict2["key2"] = "WHY?!"
>>> dict1
{'key1': 'value1', 'key2': 'value2'}
>>>

İşaretçi: Sığ ve derin copys arasındaki fark


1
Bu, derin bir kopya değil, sığ bir kopya ile sonuçlanır.
sytech

1
Bunu deniyordum ama sorun yaşıyordum. Bu yalnızca python 3.5 ve üstü için geçerlidir. python.org/dev/peps/pep-0448
ThatGuyRob

19

Python'daki atama ifadeleri nesneleri kopyalamaz, bir hedef ile bir nesne arasında bağlar oluşturur.

böylece, dict2 = dict1başvurulan dict2nesne ile nesne arasında başka bir bağlanma ile sonuçlanır dict1.

bir dikteyi kopyalamak istiyorsanız copy module,. Kopyalama modülünün iki arayüzü vardır:

copy.copy(x)
Return a shallow copy of x.

copy.deepcopy(x)
Return a deep copy of x.

Sığ ve derin kopyalama arasındaki fark yalnızca bileşik nesnelerle (listeler veya sınıf örnekleri gibi başka nesneler içeren nesneler) ilgilidir:

Bir basit bir kopyasını nesnelere içine referanslar orijinal bulunan ekler (mümkün olduğu ölçüde) ve sonra yeni bir bileşik nesnesi ve oluşturur.

Bir derin kopyalama amaçları orijinal arasından içine yeni bir bileşik nesne ve daha sonra, ardışık olarak, uçlar kopya oluşturur.

Örneğin, python 2.7.9'da:

>>> import copy
>>> a = [1,2,3,4,['a', 'b']]
>>> b = a
>>> c = copy.copy(a)
>>> d = copy.deepcopy(a)
>>> a.append(5)
>>> a[4].append('c')

ve sonuç:

>>> a
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> b
[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>> c
[1, 2, 3, 4, ['a', 'b', 'c']]
>>> d
[1, 2, 3, 4, ['a', 'b']]

10

Yapıcıyı dictek anahtar kelime bağımsız değişkenleri ile çağırarak yeni oluşturulan kopyayı tek seferde kopyalayabilir ve düzenleyebilirsiniz :

>>> dict1 = {"key1": "value1", "key2": "value2"}
>>> dict2 = dict(dict1, key2="WHY?!")
>>> dict1
{'key2': 'value2', 'key1': 'value1'}
>>> dict2
{'key2': 'WHY?!', 'key1': 'value1'}

9

Bu da beni şaşırttı, çünkü C kökenliyim.

C de bir değişken, bellekteki tanımlı tipte bir konumdur. Değişkene atamak, verileri değişkenin bellek konumuna kopyalar.

Ancak Python'da değişkenler nesnelere daha çok işaretçi gibi davranır. Bu nedenle, bir değişkeni diğerine atamak bir kopya oluşturmaz, bu değişken adını aynı nesneyi işaret eder.


5
python değişkenleri daha çok c ++ referanslarına benzer
Ruggero Turra

7
Çünkü Python'daki her şey bir nesne! diveintopython.net/getting_to_know_python/… (evet, bu yanıt uzun yıllar geçti, ama belki birileri için bazı
faydaları var

1
Python dil semantiğinin "değişken" olmadığını söylediğine inanıyorum. Bunlara "adlandırılmış referanslar" denir; yani bir nesneye yapılan referans koddaki sözdizimsel bir dizedir. Bir nesnenin kendisine birçok adlandırılmış başvurusu olabilir. Ints ve float ve str örnekleri gibi değişmez nesnelerin işlem başına yalnızca bir örneği vardır. Bu myvalue = 1 myvalue = 2 yaptığınızda, bellekte 1 int değeri aynı bellek adresindeki 2 veya başka bir değere değişmez 2
03'te DevPlayer

7

Gibi her Python değişken (malzeme dict1veya strveya __builtins__makinenin içindeki bazı gizli platonik "nesne" bir göstericidir.

Eğer ayarlarsanız dict1 = dict2, sadece işaret dict1aynı nesneye (veya hafıza konumu, ya da her türlü benzetme sizin gibi) olarak dict2. Şimdi, başvurulan nesne başvurulan dict1aynı nesne dict2.

Kontrol edebilirsiniz: dict1 is dict2olması gerekir True. Ayrıca, id(dict1)aynı olmalıdır id(dict2).

İstersen dict1 = copy(dict2), ya da dict1 = deepcopy(dict2).

copyVe deepcopy? Arasındaki fark deepcopyöğelerinin dict2(bir listeye işaret ettiniz mi?) öğelerinin de kopya olduğundan emin olacaktır .

Çok kullanmıyorum deepcopy- buna ihtiyaç duyan kod yazmak genellikle kötü bir uygulamadır (bence).


Her zaman deepcopy kullanmam gerektiğini fark ettim, böylece iç içe bir sözlük kopyalayıp iç içe girişleri değiştirmeye başladığımda, efektler orijinal değil, yalnızca kopyada gerçekleşir.
flutefreak7

6

dict1temel sözlük sözlüğüne gönderme yapan bir semboldür. Atama dict1için dict2sadece aynı başvuru atar. Bir anahtarın değerini dict2sembol aracılığıyla değiştirmek, altta yatan nesneyi de değiştirir, bu da etkiler dict1. Bu kafa karıştırıyor.

Değişmez değerleri sorgulamak referanslardan çok daha kolaydır, bu nedenle mümkün olduğunca kopya yapın:

person = {'name': 'Mary', 'age': 25}
one_year_later = {**person, 'age': 26}  # does not mutate person dict

Sözdizimsel olarak şu ile aynıdır:

one_year_later = dict(person, age=26)

5

dict2 = dict1sözlüğü kopyalamaz. Programcıya dict2aynı sözlüğe başvurmanız için ikinci bir yol ( ) verir.


5
>>> dict2 = dict1
# dict2 is bind to the same Dict object which binds to dict1, so if you modify dict2, you will modify the dict1

Dict nesnesini kopyalamanın birçok yolu var, sadece

dict_1 = {
           'a':1,
           'b':2
         }
dict_2 = {}
dict_2.update(dict_1)

12
dict_2 = dict_1.copy()çok daha verimli ve mantıklı.
Jean-François Fabre

2
Dict1 içinde bir dict varsa, dict_1.copy () ile dict_2 içindeki iç dikte yaptığınız değişikliklerin dict_1 içindeki dahili diksele de uygulandığını unutmayın. Bu durumda bunun yerine copy.deepcopy (dict_1) kullanmalısınız.
1919'da kuyruk

1

Diğerlerinin açıkladığı gibi, yerleşik dictistediğinizi yapmaz. Ancak Python2'de (ve muhtemelen 3'te) kolayca ValueDictkopyalanacak bir sınıf oluşturabilirsiniz , =böylece orijinalin değişmeyeceğinden emin olabilirsiniz.

class ValueDict(dict):

    def __ilshift__(self, args):
        result = ValueDict(self)
        if isinstance(args, dict):
            dict.update(result, args)
        else:
            dict.__setitem__(result, *args)
        return result # Pythonic LVALUE modification

    def __irshift__(self, args):
        result = ValueDict(self)
        dict.__delitem__(result, args)
        return result # Pythonic LVALUE modification

    def __setitem__(self, k, v):
        raise AttributeError, \
            "Use \"value_dict<<='%s', ...\" instead of \"d[%s] = ...\"" % (k,k)

    def __delitem__(self, k):
        raise AttributeError, \
            "Use \"value_dict>>='%s'\" instead of \"del d[%s]" % (k,k)

    def update(self, d2):
        raise AttributeError, \
            "Use \"value_dict<<=dict2\" instead of \"value_dict.update(dict2)\""


# test
d = ValueDict()

d <<='apples', 5
d <<='pears', 8
print "d =", d

e = d
e <<='bananas', 1
print "e =", e
print "d =", d

d >>='pears'
print "d =", d
d <<={'blueberries': 2, 'watermelons': 315}
print "d =", d
print "e =", e
print "e['bananas'] =", e['bananas']


# result
d = {'apples': 5, 'pears': 8}
e = {'apples': 5, 'pears': 8, 'bananas': 1}
d = {'apples': 5, 'pears': 8}
d = {'apples': 5}
d = {'watermelons': 315, 'blueberries': 2, 'apples': 5}
e = {'apples': 5, 'pears': 8, 'bananas': 1}
e['bananas'] = 1

# e[0]=3
# would give:
# AttributeError: Use "value_dict<<='0', ..." instead of "d[0] = ..."

Lütfen burada tartışılan lvalue modifikasyon modeline bakın: Python 2.7 - lvalue modifikasyonu için temiz sözdizimi . Temel gözlem şudur strve intPython'daki değerler gibi davranırlar (aslında kaputun altında değişmez nesneler olsalar da). Bunu gözlemlerken, lütfen strveya hakkında hiçbir şeyin sihirli bir şekilde özel olmadığını da gözlemleyin int. dictaynı şekilde kullanılabilir ve ValueDictmantıklı olan birçok durumu düşünebilirim .


0

Aşağıdaki kod, json sözdizimini deepcopy'den 3 kat daha hızlı izleyen dikte üzerinde

def CopyDict(dSrc):
    try:
        return json.loads(json.dumps(dSrc))
    except Exception as e:
        Logger.warning("Can't copy dict the preferred way:"+str(dSrc))
        return deepcopy(dSrc)

0

değişken atama w / o sınıfın sözlük özelliği derin kopyalamaya çalışırken tuhaf bir davranış koştu

new = copy.deepcopy(my_class.a)çalışmıyor yani modifiye newdeğiştirirmy_class.a

ancak yaparsanız old = my_class.ave sonra new = copy.deepcopy(old)mükemmel çalışırsa, yani değişiklik newetkilemezmy_class.a

Bunun neden olduğundan emin değilim, ama umarım birkaç saat kazanmanıza yardımcı olur! :)


Peki nasıl derin bir fotokopi çekersiniz my_class.a?
Anthony

En iyi yol değil. İyi yanıt feryat.
David Beauchemin

-1

çünkü dict2 = dict1, dict2, dict1 referansını tutar. Hem dict1 hem de dict2 bellekte aynı yeri gösterir. Python'da değiştirilebilir nesnelerle çalışırken bu normal bir durumdur. Python'da değiştirilebilir nesnelerle çalışırken hata ayıklamak zor olduğundan dikkatli olmalısınız. Aşağıdaki örnek gibi.

 my_users = {
        'ids':[1,2],
        'blocked_ids':[5,6,7]
 }
 ids = my_users.get('ids')
 ids.extend(my_users.get('blocked_ids')) #all_ids
 print ids#output:[1, 2, 5, 6, 7]
 print my_users #output:{'blocked_ids': [5, 6, 7], 'ids': [1, 2, 5, 6, 7]}

Bu örnek amaç, engellenen kimlikler dahil tüm kullanıcı kimliklerini elde etmektir. İds değişkeninden aldık ama kasıtsız olarak my_users değerini de güncelledik . Eğer uzatılmış kimlikleri ile blocked_ids çünkü my_users güncellenen gördü kimlikleri bakın my_users .


-1

For döngüsü kullanarak kopyalama:

orig = {"X2": 674.5, "X3": 245.0}

copy = {}
for key in orig:
    copy[key] = orig[key]

print(orig) # {'X2': 674.5, 'X3': 245.0}
print(copy) # {'X2': 674.5, 'X3': 245.0}
copy["X2"] = 808
print(orig) # {'X2': 674.5, 'X3': 245.0}
print(copy) # {'X2': 808, 'X3': 245.0}

1
Bu sadece basit sözlükler için geçerlidir. Neden deepcopybu amaç için özel olarak inşa edilmiş kullanmıyorsunuz ?
Anthony

En iyi yol değil. İyi yanıt feryat.
David Beauchemin

-6

Doğrudan kullanabilirsiniz:

dict2 = eval(repr(dict1))

burada dict2 nesnesi dict1 öğesinin bağımsız bir kopyasıdır, böylece dict2 öğesini dict1'i etkilemeden değiştirebilirsiniz.

Bu her türlü nesne için işe yarar.


4
Bu cevap yanlış ve kullanılmamalıdır. Örneğin, kullanıcı tanımlı bir sınıf, __repr__eval tarafından yeniden yapılandırılmaya uygun olmayabilir veya nesnenin sınıfı, çağrılacak geçerli kapsamda olmayabilir. Yerleşik türlere bağlı kalsanız bile, aynı nesne dict2iki ayrı nesnede olduğu gibi aynı nesne birden fazla anahtar altında saklanırsa başarısız olur . Kendini dict1içeren bir öz referans sözlüğü bunun yerine içerecektir Ellipsis. Kullanmak daha iyi olurdudict1.copy()
Eldritch Cheese

Nesnelerin (veya "değerlerin") karakter dizeleriyle her zaman sadık bir temsili olması beklenmez, her durumda insan tarafından okunabilir şekilde değil.
Alexey
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.