Anfänger frage zu for x 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
ravenheart
User
Beiträge: 70
Registriert: Mittwoch 10. November 2010, 18:41

Hallo, darf ich so etwas machen?

Code: Alles auswählen

x = liste

for element in liste:
  element = foo(element)
  print irgendwas

Dürfen ist vlt falsch ausgedrückt, vielmehr will ich wissen, ob so etwas Einfluss auf meine Iteration hat, oder ich so ein element bearbeiten kann
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Wieso sollte das einen Einfluß auf die Iteration haben? Du iterierst doch über "liste" und nicht über "element". Was du mit dem "element" machst ist der Liste ziemlich egal.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Rekrul
User
Beiträge: 78
Registriert: Dienstag 7. Dezember 2010, 16:23

Das 'darfst' du natürlich schon machen. Es ist allerdings je nach dem was du erwartest sinnvoll oder eben nicht sinnvoll. In folgendem Beispiel verändert du die Liste nicht, da es sich um skalare Werte handelt.

Code: Alles auswählen

x = [1,2,3]

def increment(value):
    return value + 1

for e in x:
    e = increment(e)
    print(e)

print(x)
Die Ausgabe wäre hier folgende:

Code: Alles auswählen

2
3
4
[1,2,3]
Hast du allerdings eine List mit Referenzen passiert folgendes:

Code: Alles auswählen

class A(object):
    def __init__(self, x):
        self.x = x

    def __add__(self, y):
        return self.x + y

    def __str__(self):
        return str(self.x)

    def __repr__(self):
        #Eigentlich ganz boese!
        return str(self.x)

x = [A(1), A(2), A(3)]

def increment(value):
    return value + 1

for e in x:
    e = increment(e)
    print(e)

print(x)
Ausgabe:

Code: Alles auswählen

2
3
4
[2,3,4]
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Du darfst nur nicht am Inhalt von "liste" herumpfuschen. Wenn sich da im Schleifenablauf etwas verändern soll müsstest du vorher eine Kopie der Liste ziehen. Ansonsten "kotzt" der Interpreter. ;)
BlackJack

@mkesper: Das ist so allgemein gesagt nicht richtig. Man muss sich bei Änderungen nur über die Auswirkungen im Klaren sein.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Dass folgendes in die Hosen geht, ist klar:

Code: Alles auswählen

my_list = [1, 2, 3]
for e in my_list:
    print e
    my_list.append(e)
Aber weshalb geschieht dasselbe nicht auch hier:

Code: Alles auswählen

my_string = 'hallo'
for e in my_string:
    print e
    my_string += e.upper()
Das heißt, es passiert hier nur beim ersten Durchlauf über 'my_string'. Weshalb?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Weil strings in Python immutable sind! Dein Name `my_string` im Schleifenrumpf ist ein vollkommen neues Objekt. (Übrigens wird bei jedem Durchlauf ein neues Objekt angelegt... ein Grund, wieso man String-Konkatinierung mittels "+" meiden sollte).

Kannst Dir ja mal die `id()` ausgeben lassen, da sollte es zeigen.

Edit: Nee, zeigt es nicht. Augenscheinlich ist der Interpreter schlau und weist dem neuen Objekt immer wieder den selben Speicherbereich zu.

Aber so kann man es sich ja auch klar machen:

Code: Alles auswählen

In [24]: my_string = 'hallo'

In [25]: foo = my_string

In [26]: foo is my_string
Out[26]: True

In [28]: for e in my_string:
    print e
    my_string += e.upper()
    print id(my_string), id(foo)
    print my_string is foo
   ....:     
   ....:     
h
153407904 153533600
False
a
153407904 153533600
False
l
153407904 153533600
False
l
153407904 153533600
False
o
153407904 153533600
False
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten