Variabeln in Schleifen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
n3xtplayer
User
Beiträge: 36
Registriert: Sonntag 2. Oktober 2011, 12:13

Dienstag 18. Oktober 2011, 10:11

Hey zusammen

Hab nochmal ein kleines Problem, das ich irgendwie nicht ganz bewältigen kann. Aber ich habe eigentlich das Gefühl das sollte doch irgendwie einfach zu machen sein. Wenn ich während einer Schleife eine Variable verändere, wie z.B. a = a+1, ist es dann möglich, diese Variable vor jedem Durchlauf der Schleife wieder zu ''refreshen''?
Beispiel:

Code: Alles auswählen

def schleife(a,b):
	for i in range(a):
		b = b+1
		print(b)
Ist es also hier möglich, dass (angenommen a=10, b = 1)ich nicht die Resultate 2,3,4,5,6,7,8,9,10,11 bekomme, sondern einfach 2,2,2,2,2,2,2,2,2,2,2?
Danke schon im voraus und LG
Benutzeravatar
/me
User
Beiträge: 3212
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Dienstag 18. Oktober 2011, 10:25

Verwende eine weitere Variable und ändere das Original nicht.

Code: Alles auswählen

def schleife(a,b):
    for i in range(a):
        c = b
        c = c + 1
        print(c)
Und verwende in deinem Code besser 4 Leerzeichen als einen Tabulatorschritt zum Einrücken
deets

Dienstag 18. Oktober 2011, 10:27

Ich verstehe nicht so ganz, was du da machen willst. Dein Problem loest sich doch total simpel mit

Code: Alles auswählen


def schleife(a,b):
        b = b+1
        for i in range(a):
                print(b)
Und generell gilt: Variablen bzw. Namen, die an Werte gebunden sind, haben kein "Gedaechtnis". Du musst also sowas explizit programmieren, indem du zB eine temporaere Variable einfuehrts:


def schleife(a,b):
for i in range(a):
c = b + 1
print(c)
[/code]
n3xtplayer
User
Beiträge: 36
Registriert: Sonntag 2. Oktober 2011, 12:13

Dienstag 18. Oktober 2011, 10:37

danke euch, hab nach irgendeiner ''refresh''-funktion oder so gesucht und das naheliegende ganz übersehen.
@deets: Dieses Problem lässt sich schon recht einfach lösen, doch es ist eigentlich nur als kleines Beispiel gedacht :)
LG
n3xtplayer
User
Beiträge: 36
Registriert: Sonntag 2. Oktober 2011, 12:13

Dienstag 18. Oktober 2011, 17:33

/me hat geschrieben:Verwende eine weitere Variable und ändere das Original nicht.

Code: Alles auswählen

def schleife(a,b):
    for i in range(a):
        c = b
        c = c + 1
        print(c)
Hallo nochmal. Ich habe gerade gemerkt dass das nur funktioniert wenn man für die Variable eine Zahl gesetzt hat, wie z.B. b= 1.
Wenn ich jedoch eine Liste habe, z.B. b = [1,2,3], dann c = b setze und dann von c mit c.remove(1) die 1 entferne dann wird diese 1 auch in b entfernt. Und genau das ist mein Problem... Habt ihr eine Idee wie ich das lösen könnte? Hier ist das Beispiel:

Code: Alles auswählen

>>> def schleife(a, b=[1,2,3]):
	for i in range(a):
		c = b
		c.remove(1)
		print(c)

		
>>> schleife(10)
[2, 3]
Traceback (most recent call last):
  File "<pyshell#98>", line 1, in <module>
    schleife(10)
  File "<pyshell#97>", line 4, in schleife
    c.remove(1)
ValueError: list.remove(x): x not in list
Lg
deets

Dienstag 18. Oktober 2011, 17:41

Das ist logisch, denn bei einer Liste handelt es sich um ein "mutable" - also ein veraenderliches Objekt. Und Python hat (im Gegensatz zB zu PHP) keine Copy-Semantik bei Zuweisung an einen andere Variable. Das hoert sich komisch an, meint aber nur, dass Variablen in Python immer nur auf ein Objekt zeigen, und es auch problemlos moeglich ist, viele Namen auf dasselbe Objekt zeigen zu lassen. Wenn das dann modifieziert wird, dann "sieht" man das auch durch alle anderen Namen hindurch.

Darum musst du bei solchen Sachen eine *explizite* Kopie anfertigen. Dafuer gibt's diverse Moeglichkeiten, lies dir auf jeden Fall mal die Dokumentation zum Modul "copy" durch.

Fuer deinen simplen Fall sollte aber ein

Code: Alles auswählen

c = list(b)
reichen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dienstag 18. Oktober 2011, 17:44

Kleiner Tipp dazu:

Code: Alles auswählen

In [79]: a = range(5)

In [80]: a
Out[80]: [0, 1, 2, 3, 4]

In [81]: b = a

In [82]: b is a
Out[82]: True
a und b sind nur Namen, das von `range` erzeugte Listenobjekt ist aber nur einmal im Spicher vorhanden! [82] zeigt das: Mittels `is`-operator kann man prüfen, ob zwei Namen an dasselbe Objekt gebunden sind.

Du suchst das `copy`-Modul. Damit kannst Du echte Kopien von Objekten erstellen:

Code: Alles auswählen

In [83]: import copy

In [84]: b = copy.copy(a)

In [85]: b is a
Out[85]: False

In [86]: b.pop()
Out[86]: 4

In [87]: b
Out[87]: [0, 1, 2, 3]

In [88]: a
Out[88]: [0, 1, 2, 3, 4]
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3))
assert encoding_kapiert
BlackJack

Dienstag 18. Oktober 2011, 18:35

@n3xtplayer: Neben dem bereits gesagt stellt sich oft die Frage ob man eine vorhandene Datenstruktur überhaupt verändern muss, oder ob man nicht eine neue erstellen kann/sollte. Das macht das Kopieren der Liste vor der Schleife zwar, aber ich meinte jetzt eher statt eine Kopie zu erstellen und daraus Werte zu entfernen, eine neue Liste zu erstellen, in die erst gar nicht die Werte hinein getan werden, die man sonst entfernt hätte.
n3xtplayer
User
Beiträge: 36
Registriert: Sonntag 2. Oktober 2011, 12:13

Mittwoch 19. Oktober 2011, 16:48

BlackJack hat geschrieben:@n3xtplayer: Neben dem bereits gesagt stellt sich oft die Frage ob man eine vorhandene Datenstruktur überhaupt verändern muss, oder ob man nicht eine neue erstellen kann/sollte. Das macht das Kopieren der Liste vor der Schleife zwar, aber ich meinte jetzt eher statt eine Kopie zu erstellen und daraus Werte zu entfernen, eine neue Liste zu erstellen, in die erst gar nicht die Werte hinein getan werden, die man sonst entfernt hätte.

Ich kann die Objekte noch nicht aus der Liste entfernen, denn ich weiss noch nicht wie die Objekte heissen. Die Liste ist ein Deck und die Objekte sin Karten. Durch random.shuffle(D) wird bei jedem neuen Durchlauf der Schleife eine andere Karte zu oberst liegen und kurz darauf entfernt werden. Lustiger Zufall dass du Blackjack heisst, ich schreibe nämlich gerade ein paar kleine Programme um die beste Strategie in Black Jack zu ''berechnen''. :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Mittwoch 19. Oktober 2011, 18:38

n3xtplayer hat geschrieben:
Ich kann die Objekte noch nicht aus der Liste entfernen, denn ich weiss noch nicht wie die Objekte heissen.
BlackJack wollte ja auch darauf hinaus, dass man anstelle des Entfernens manchmal besser einfach eine neue Liste mit den gewollten Elementen anlegt!

Nebenbei ergibt Dein Satz im Kontext wenig Sinn - denn oben hast Du uns ja ständig Code gezeigt, in dem Du Elemente aus einer Liste entfernst! Da widersprichst Du Dir ja selber... :!:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3))
assert encoding_kapiert
n3xtplayer
User
Beiträge: 36
Registriert: Sonntag 2. Oktober 2011, 12:13

Donnerstag 20. Oktober 2011, 09:38

Ja das war nur ein Besipiel, da ich nicht meinen ganzen Quelltext posten wollte. Denn der ist im Moment noch etwas unübersichtlicht.
Und das Beispiel war gar nicht so schlecht, denn genau das was ich gesucht habe, war dieses copy - modul, das ihr mir gezeigt habt :). Insofern hat Blackjack natürlich recht, denn ich habe gar nie gesagt, dass das ganze in meinem Programm ganz anders aussieht....
Antworten