1267 Stimmen

Wie man ein Wörterbuch kopiert und nur die Kopie bearbeitet

Ich setze dict2 = dict1. Wenn ich dict2 bearbeite, ändert sich auch das Original dict1. Warum?

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

3voto

Der folgende Code, der sich auf Dicts befindet, die dem JSON-Syntax folgen, ist mehr als 3 Mal schneller als deepcopy

def CopyDict(dSrc):
    try:
        return json.loads(json.dumps(dSrc))
    except Exception as e:
        Logger.warning("Kann das Dictionary nicht auf bevorzugte Weise kopieren:"+str(dSrc))
        return deepcopy(dSrc)

2voto

personal_cloud Punkte 3453

Wie andere bereits erklärt haben, tut das integrierte dict nicht das, was du willst. Aber in Python2 (und wahrscheinlich auch 3) kannst du ganz einfach eine ValueDict-Klasse erstellen, die mit = kopiert, sodass du sicher sein kannst, dass das Original sich nicht ändert.

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, \
            "Verwende \"value_dict<<='%s', ...\" anstelle von \"d[%s] = ...\"" % (k,k)

    def __delitem__(self, k):
        raise AttributeError, \
            "Verwende \"value_dict>>='%s'\" anstelle von \"del d[%s]" % (k,k)

    def update(self, d2):
        raise AttributeError, \
            "Verwende \"value_dict<<=dict2\" anstelle von \"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']

# Ergebnis
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
# würde folgendes ausgeben:
# AttributeError: Verwende "value_dict<<='0', ..." anstelle von "d[0] = ..."

Bitte beachte das hier diskutierte Modell der LVALUE-Änderung: Python 2.7 - saubere Syntax für LVALUE-Änderung. Die entscheidende Beobachtung ist, dass str und int sich in Python wie Werte verhalten (obwohl sie eigentlich unter der Haube unveränderliche Objekte sind). Während du das beobachtest, beachte bitte auch, dass nichts magisch an str oder int ist. dict kann auf ähnliche Weise verwendet werden, und ich kann mir viele Fälle vorstellen, in denen ValueDict Sinn macht.

1voto

Anushk Punkte 472

Ich bin auf ein eigenartiges Verhalten gestoßen, als ich versuchte, die Dictionary-Eigenschaft einer Klasse ohne Zuweisung an eine Variable zu tief zu kopieren

neu = copy.deepcopy(my_class.a) funktioniert nicht d.h. das Modifizieren von neu ändert my_class.a

aber wenn du alt = my_class.a machst und dann neu = copy.deepcopy(alt), funktioniert es perfekt, d.h. das Modifizieren von neu beeinträchtigt nicht my_class.a

Ich bin mir nicht sicher, warum dies passiert, aber ich hoffe, es hilft, einige Stunden zu sparen! :)

0voto

Kopieren mit einer for-Schleife:

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}

-4voto

Viiik Punkte 25

Sie können direkt verwenden:

dict2 = eval(repr(dict1))

wobei das Objekt dict2 eine unabhängige Kopie von dict1 ist, so dass Sie dict2 modifizieren können, ohne dict1 zu beeinflussen.

Dies funktioniert für jedes Objekt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X