2016-07-05 3 views
0

Ich habe eine Art von Objekt, data_entry, die ein 2-dimensionales Array von anderen Objekten hat, time_entry.Python: Ändern eines einzelnen Objekts innerhalb eines Arrays von Objekten ändert alle, auch in einem anderen Array

Initialisierung von time_entries das Array innerhalb data_entry sieht wie folgt aus:

[([time_entry()] * 12) for i in range(5)] 

und Initialisierung des data_entry wie folgt aussieht:

thing = data_entry() 

Nun ich eine Liste der "Dinge", die jeweils das enthält sein eigenes 2d Array von time_entry s.

time_entry Jeder hat eine Liste als eine seiner Attribute, wie so initialisiert:

attributes = [] 

I Attribute modifizieren, indem es unter Verwendung von .extend() erstreckt.

Allerdings läuft das Problem, wenn ich dies tun, ist jede einzelne time_entry Objekt in jeder einzelnen data_entry Objekt wird erweitert.

Ich weiß, dass Probleme wie diese durch unsachgemäße Initialisierung von Objekten entstehen können, also frage ich mich, ob vielleicht meine Objektkreationen arm sind oder es eine andere Python-Eigenart gibt, die mir nicht bewusst ist.

+0

Können Sie ein minimales Arbeitsbeispiel posten? –

+0

Siehe auch http://stackoverflow.com/questions/240178/python-list-of-lists-changes-reflected-across-sublists-unexpectedly –

+0

Ich fürchte, die Antwort auf diese Frage löst ein anderes Problem. –

Antwort

1

Wenn Sie die Initialisierung von der Klasse ausführen, werden alle Instanzen der Klasse beeinflussen. Wenn dies der Fall ist, ist das nicht darauf zurückzuführen, dass es in einer Liste ist, sondern in der Klasse. Zum Beispiel:

#!/usr/bin/python 

class BedrockDenizen(): 
    attributes = [] 


wilma = BedrockDenizen() 
fred = BedrockDenizen() 

wilma.attributes.extend(['thin', 'smart']) 
fred.attributes.extend(['fat', 'stupid']) 

print 'Wilma:', wilma.attributes 
print 'Fred:', fred.attributes 

Sie werden sehen, dass sowohl Fred und Wilma sind dünn, smart, Fett und dumm.

Wilma: [ 'dünn', 'smart', 'Fett', 'dumm']

Fred: [ 'dünn', 'smart', 'Fett', 'dumm']

eine Möglichkeit, dies zu beheben, ist das Attribut Schöpfung in die init Methode zu setzen, so dass das Attribut pro Instanz ist:

class BedrockDenizen(): 
    def __init__(self): 
     self.attributes = [] 

Mit dieser Änderung nur Wilma dünn und klug ist, ein Nur Fred ist dick und dumm.

Wilma: [ 'dünn', 'intelligente']

Fred: [ 'Fett', 'dumm']

Sie uns auch mehr Code zu erhalten müssen. @Bakuriu stellt fest, dass das Problem möglicherweise darin besteht, dass Sie nur eine Instanz erstellen und er möglicherweise Recht hat. Zum Beispiel ist, wenn diese näher an den Code:

class BedrockDenizen(): 
    def __init__(self): 
     self.attributes = [] 

neighborhood = [([BedrockDenizen()] * 2) for i in range(2)] 

flintstones, rubbles = neighborhood 
fred, wilma = flintstones 

wilma.attributes.extend(['thin', 'smart']) 
fred.attributes.extend(['fat', 'stupid']) 

print 'Wilma:', wilma.attributes 
print 'Fred:', fred.attributes 

Dann Fred und Wilma wird auch weiterhin die gleichen Attribute haben, weil sie nicht wirklich getrennt Menschen sind. Vielleicht möchten Sie Code wie diesen mehr verwenden:

class BedrockDenizen(): 
    def __init__(self): 
     self.attributes = [] 

neighborhood = [[BedrockDenizen() for n in range(2)] for i in range(2)] 

flintstones, rubbles = neighborhood 
fred, wilma = flintstones 

wilma.attributes.extend(['thin', 'smart']) 
fred.attributes.extend(['fat', 'stupid']) 

print 'Wilma:', wilma.attributes 
print 'Fred:', fred.attributes 

Das hängt davon ab, was Ihre Bedürfnisse sind, obwohl, wie es wie eine seltsame Art und Weise scheint ohne weitere Informationen, Dinge zu tun.

+2

Dies ist ein ** anderes, nicht verwandtes ** Problem. Ich sehe in diesem Code keine "[Objekt] * Nummer", was die Probleme von OP verursacht. – Bakuriu

+0

@JerryStratton: Nein, '[Objekt] * n 'erstellt eine Liste von' n' Einträgen, die alle dasselbe Objekt sind. Es macht keine neuen Objekte. – user2357112

+0

Ja, ich denke, das könnte richtig sein. Probieren Sie es aus OP – Anonymous

Verwandte Themen