Seite 1 von 1

Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 10:03
von kruhling
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 10:13
von sls
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 10:23
von ThomasL

Code: Alles auswählen

liste2 = liste1
Versuche es so zu sehen;
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)

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 10:24
von kbr
@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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 10:31
von ThomasL
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

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 11:20
von __deets__
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.
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 11:22
von Astorek
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.
Wobei das (scheinbar? Bin auch nicht so tief drin in der Materie...) auch nicht bei allen Datentypen der Fall ist:

Code: Alles auswählen

>>> a = 5
>>> b = a
>>> a = 6
>>> a
6
>>> b
5
Bei Listen und Dictonaries ist der Fall hingegen eindeutig, da teilen sich idR. ein Speicherbereich zwei Variablennamen (oder mehr, falls man weitere verwendet und auf dieselbe Liste bzw. Dictionary zeigt). Hier muss man explizit die Liste bzw. Dictionary kopieren, ansonsten referenziert man nur auf ein- und denselben Speicherbereich. Eben mit den Beispielen, die ThomasL geschrieben hat...

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 11:26
von __deets__
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 11:31
von Astorek
__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.
Ich bin ein Idiot. Danke, macht Sinn; mein Kopf ist heute wohl noch nicht vom Bett aufgestanden^^...

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 16:40
von kruhling
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 16:46
von Sirius3
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.

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 17:43
von Tholo
@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?!?

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]

Re: Anfängerfrage zu Listen

Verfasst: Sonntag 1. Juli 2018, 17:50
von __deets__
@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.