Hallo zusammen,
ich habe gerade angefangen, mich mit Python zu beschäftigen und bin dabei auf Problem gestoßen.
Ich kenne es von anderen Sprachen, dass die Anweisung
liste2=liste3
die liste3 in die liste2 kopiert. Danach ist liste3 noch vorhanden, nur eben kopiert und somit doppelt.
Beim Üben bin ich nun darauf gestoßen, dass Python das offenbar anders macht. Ich habe ein kleines Beispielprogramm geschrieben ( eine Übung aus einem Buch ):
# 2. Programm zu Listen
# Liste initialisieren
namen=[]
# MAIN
print "Gib bitte 5 Namen ein:"
for i in range(5):
tempname=raw_input()
namen.append(tempname)
# ursprüngliche Liste in sortname ablegen und dann sortnamen sortieren
sortnamen=namen
sortnamen.sort()
print namen
print sortnamen
Wenn ich das so tue und dann namen und sortnamen ausgebe, sind sie gleich. Mache ich hier etwas falsch, oder was löst dieses Verhalten aus?
Vielen Dank für eure Hilfe.
Anfängerfrage zu Listen
- sls
- User
- Beiträge: 480
- Registriert: Mittwoch 13. Mai 2015, 23:52
- Wohnort: Country country = new Zealand();
Bitte setze deinen Code das nächste mal in Python-Code-Tags, damit das hier entsprechend formatiert wird. Sonst ist der Code kaum lesbar.
In Python wird das IMO so gehandhabt, wie in jeder anderen Sprache die ich kenne (Java, C, C# usw. usf) auch: der Inhalt des rechts vom "="-Zeichen stehenden Bezeichners wird in den links vom "="-Zeichen stehenden Bezeichners übergeben. Beide Variablen, bzw. deine Liste namen und sortnamen *zeigen* dabei auf die selbe Speicheradresse in deinem RAM.
In Python wird das IMO so gehandhabt, wie in jeder anderen Sprache die ich kenne (Java, C, C# usw. usf) auch: der Inhalt des rechts vom "="-Zeichen stehenden Bezeichners wird in den links vom "="-Zeichen stehenden Bezeichners übergeben. Beide Variablen, bzw. deine Liste namen und sortnamen *zeigen* dabei auf die selbe Speicheradresse in deinem RAM.
When we say computer, we mean the electronic computer.
Code: Alles auswählen
liste2 = liste1
Der Variablenname liste1 ist eine Referenz, ein Pointer/Zeiger auf eine Liste von Objekten.
Bei der Zuweisung wird diese Referenz kopiert, aber nicht eine Kopie der Liste erzeugt.
Wenn du eine Kopie erzeugen willst, gibt es dafür mehrere Möglichkeiten:
Code: Alles auswählen
# slicing
liste2 = liste1[:]
# Benutzung der list() Funktion
liste2 = list(liste1)
# Benutzung des copy Moduls, ist aber langsamer
import copy
liste2 = copy.deepcopy(liste1)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
@kruhling: Für das, was Du möchtest, gibt es die Funktion 'sorted'. Dann solltest Du berücksichtigen, dass 'Variablen' in Python tatsächlich stets Referenzen auf Objekte sind. So legt 'a = b' beispielsweise mit a eine zweite Referenz auf das Objekt an, welches bereits durch b referenziert wird. Wichtig für das weitere Verständnis ist die Unterscheidung von mutablen und immutablen Datentypen.
Wenn du die englische Sprache einigermaßen verstehst, schau dir mal diesen Talk an,
insbesondere die ersten 20 min behandeln diese Thematik.
Learn Python by Immersion https://www.youtube.com/watch?v=hPECpDHHjoI
insbesondere die ersten 20 min behandeln diese Thematik.
Learn Python by Immersion https://www.youtube.com/watch?v=hPECpDHHjoI
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Das ist ein bisschen sehr verallgemeinert. Auch Java, C und C# erstellen Kopien, wenn es sich um Wertetypen handelt. Zb Strukturen in C, und mindestens mal primitive Datentypen bei allen. C++ hingegen macht mit seinen Standardcontainern sogar immer ein Kopie, weil es da explizite Referenztypen (und natürlich Pointer) gibt. Falls das also die “andere” Sprache des TEs ist, ist das überraschend. Genauso auch in PHP.sls hat geschrieben: ↑Sonntag 1. Juli 2018, 10:13 In Python wird das IMO so gehandhabt, wie in jeder anderen Sprache die ich kenne (Java, C, C# usw. usf) auch: der Inhalt des rechts vom "="-Zeichen stehenden Bezeichners wird in den links vom "="-Zeichen stehenden Bezeichners übergeben. Beide Variablen, bzw. deine Liste namen und sortnamen *zeigen* dabei auf die selbe Speicheradresse in deinem RAM.
Wobei das (scheinbar? Bin auch nicht so tief drin in der Materie...) auch nicht bei allen Datentypen der Fall ist:kbr hat geschrieben: ↑Sonntag 1. Juli 2018, 10:24 @kruhling: Für das, was Du möchtest, gibt es die Funktion 'sorted'. Dann solltest Du berücksichtigen, dass 'Variablen' in Python tatsächlich stets Referenzen auf Objekte sind. So legt 'a = b' beispielsweise mit a eine zweite Referenz auf das Objekt an, welches bereits durch b referenziert wird. Wichtig für das weitere Verständnis ist die Unterscheidung von mutablen und immutablen Datentypen.
Code: Alles auswählen
>>> a = 5
>>> b = a
>>> a = 6
>>> a
6
>>> b
5
Es ist so. 5 und 6 sind halt zwei verschiedene Objekte. Die jeweils unveränderlich sind, wobei das für die Betrachtung keine Rolle spielt. Denn dein Beispiel belegt nur, was kbr sagt: eine Zuweisung bedeutet nur einen Namen auf ein Objekt zeigen zu lassen. Du hast zwei Namen, die auf das gleiche Objekt zeigen, aber dann hängst du einen um.
Ich bin ein Idiot. Danke, macht Sinn; mein Kopf ist heute wohl noch nicht vom Bett aufgestanden^^...__deets__ hat geschrieben: ↑Sonntag 1. Juli 2018, 11:26 Es ist so. 5 und 6 sind halt zwei verschiedene Objekte. Die jeweils unveränderlich sind, wobei das für die Betrachtung keine Rolle spielt. Denn dein Beispiel belegt nur, was kbr sagt: eine Zuweisung bedeutet nur einen Namen auf ein Objekt zeigen zu lassen. Du hast zwei Namen, die auf das gleiche Objekt zeigen, aber dann hängst du einen um.
Hallo zusammen,
vielen Dank für eure vielen Antworten. Wenn nicht der Inhalt, sondern eine Referenz kopiert wird, erklärt das meine Frage und dann verstehe ich auch, warum das dann diesen Effekt hat. Ich danke euch.
Wie muss ich vorgehen, wenn ich jetzt wirklich eine Kopie anlegen will?
Danke.
vielen Dank für eure vielen Antworten. Wenn nicht der Inhalt, sondern eine Referenz kopiert wird, erklärt das meine Frage und dann verstehe ich auch, warum das dann diesen Effekt hat. Ich danke euch.
Wie muss ich vorgehen, wenn ich jetzt wirklich eine Kopie anlegen will?
Danke.
Gruß, Kruhling
Das hat ja ThomasL schon geschrieben. Aber ehrlich gesagt, braucht man viel seltener eine Kopie, als man nun am Anfang denken würde. Kopie braucht man ja nur, wenn man die Liste ändern will, aber statt eine Liste zu ändern, macht man normalerweise einfach eine neue Liste.
@ThomasL
Wieso willst du ein Modul "Copy" importieren? Is doch alles dabei (zumindest weiß ich das bei Py3) was zum Listenkopieren benötigt wird.
Hab das grad nochmal probiert und es geht.Oder hab ich die Frage falsch verstanden?!?
Wieso willst du ein Modul "Copy" importieren? Is doch alles dabei (zumindest weiß ich das bei Py3) was zum Listenkopieren benötigt wird.
Hab das grad nochmal probiert und es geht.Oder hab ich die Frage falsch verstanden?!?
Code: Alles auswählen
liste1 = [1,2,3]
liste2 = Liste1 #bei zeigen auf das gleiche Objekt
liste2.append(4) # neues Objekt mit 4 dazu
print("list1: ", liste1)
print("list2: ", liste2)
liste3 = liste1.copy() # neues Objekt, wie 1 wird kopiert
print("list3: ", liste3)
Code: Alles auswählen
list1: [1, 2, 3]
list2: [1, 2, 3, 4]
list3: [1, 2, 3]
@Tholo: das gilt aber nur für die oberste Ebene. Für eine tiefe Kopie die auch Listen in Listen oder andere Datenstrukturen kopiert muss man tiefer in die Trickkiste greifen. Insbesondere wenn dann noch Rekursion dazu kommt. Da nimmt man besser copy.deepcopy.