Seite 1 von 1

liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 16:08
von Nitrama
Hallo,

ich bin ein Neuling habe aber schon ein paar andere Programmiersprachen "gelärnt"(ich kann damit umgehen).

Jetzt bin ich mal bei Python gelandet.
Und mir ist da was bei einem Programm aufgefallen.

Code: Alles auswählen

def test(testlist):
	testlist[2] = "mist"

def main():
	matrix = [0,1,2,3,4,5,6,7]
	print(matrix[2])
	test(matrix)
	print(matrix[2])
	
if __name__ == '__main__':
	main()
	
die ausgabe ist

Code: Alles auswählen

2
mist
Eigendlich müsste doch "matrix" unangetastet bleiben!
Kann mir jemand erklären warum die Liste in der Funktion geädert wird?

Mit Freundlichen Grüßen Nitrama

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 16:12
von jerald_vonRiva
Hallo, fange gerade selber mit Python an. Warum Matrix geändert wird, weil beim Aufruf der Methode Test, wird die Liste Matrix übergeben. Da dies eine Übergabe der Speicherreferenz ist zeigt die Variable testlist auf den gleichen Inhalt (Speicheradresse) wie Matrix. Dies hat zur Folge das der dritte Wert in Matrix geändert wird. In diesem Fall halt von "2" auf "mist".

mfg

Seph

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 16:15
von BlackJack
@Nitrama: Da gibt's nicht viel zu erklären, das ist *so*. In Python werden bei Zuweisungen und Parameterübergaben *nie* Werte kopiert. Es wird *die* Liste übergeben und wenn Du die in der Funktion veränderst dann ist das natürlich überall sichtbar wo auf diese Liste zugegriffen werden kann. Das ist auch nicht wirklich ungewöhnlich, es gibt viele Programmiersprachen bei denen das so ist. Java und C# um mal zwei ”aktuelle” zu nennen. Wenn man beispielsweise von QuickBasic kommt, findet man so ein Verhalten dagegen ”überraschend”.

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 16:51
von Nitrama
Und wie kann ich das verhalten ädern?

Komme von AutoIt, PHP, JavaScript bissel Assembler. :-)

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 17:10
von /me
Nitrama hat geschrieben:Und wie kann ich das verhalten ädern?
Gar nicht. Du kannst natürlich einfach eine Kopie der Liste übergeben.

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 17:32
von Nitrama
ich habs jetzt so hinbekommen.

Code: Alles auswählen

from copy import copy, deepcopy
def test(testlist):
	backup = deepcopy(testlist)
	backup[2] = "mist"

def main():
	matrix = [0,1,2,3,4,5,6,7]
	print(matrix[2])
	test(matrix)
	print(matrix[2])
	
if __name__ == '__main__':
	main()
gibts eine schnellere funktion als "deepcopy".
In meiner "richtigen" Programm habe ich 3D listen, blos zum verständnis.

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 17:43
von BlackJack
@Nitrama: Ich weiss nicht wie's bei AutoIt ist, aber bei JavaScript hast Du das gleiche Verhalten wie bei Python und bei Assembler kann man (bei den gängigen Prozessoren) auch kein Array als Kopie übergeben sondern nur die Startadresse und gegebenenfalls die Länge und muss dann beim Aufrufer oder beim Aufrufenden explizit kopieren.

`copy.deepcopy()` wäre die offensichtliche Lösung für solche Listen, allerdings würde ich zwei Fragen stellen a) brauchst Du das tatsächlich oder kannst Du statt die Struktur zu verändern nicht einfach einen *neue* mit den Veränderungen erstellen? Falls nicht, könnte es Sinn machen Numpy-Arrays zu verwenden? Die haben eine `copy()`-Methode.

Edit: JavaScript-Beispiel:

Code: Alles auswählen

var foo = function (arg) { arg[2] = 42; }

var spam = [1, 2, 3, 4];
foo(spam);
console.log(spam);

Re: liste wird in funktion geädert

Verfasst: Donnerstag 3. Dezember 2015, 17:50
von Nitrama
mit javascript ist mir das noch nie Aufgefallen :-)

Ich werde mir mal numpy anschauen.
Ich melde mich und zeige meinen Lösungsvorschlag.


EDIT:
habs jetzt so gemacht.

Code: Alles auswählen

import numpy
def test(testlist):
	backup = numpy.copy(testlist)
	backup[2] = "666"

def main():
	matrix = numpy.array([0,1,2,3,4,5,6,7],int) #gleicher Typ muss gegeben sein
	print(matrix[2])
	test(matrix)
	print(matrix[2])
	
if __name__ == '__main__':
	main()
Ich danke euch für eure Hilfe :-)

Re: liste wird in funktion geädert

Verfasst: Freitag 4. Dezember 2015, 11:10
von __deets__
PHP macht das tatsaechlich so - alles by value. Dafuer gibt es dann Referenzen, wenn man das nicht moechte. Und seinen Verstand verlieren noch dazu.