Listen verändern im Loop#

Oft verwendet man For-Loops nicht nur, um auf die Elemente einer Liste (oder eines sonstigen iterierbaren Objektes) nacheinander zuzugreifen, sondern diese auch zu verändern. Dabei gibt es zwei verschiedene Wege, Elemente einer Liste innerhalb eines For-Loops zu verändern und man muss je nachdem, mit welchen Objekten man es innerhalb der Liste zu tun hat, einen bestimmten Weg wählen. Zu unterscheiden sind dabei sogenannte unveränderbare Objekte und veränderbare Objekte.

Bei veränderbaren Objekten können wir diese unter Umständen direkt anhand der Schleifenvariable verändern. Bei unveränderbaren Objekten hingegen ändert sich bei Veränderung der Schleifenvariable nichts am repräsentierten Objekt. In diesem Fall muss das Objekt per Listenindizierung direkt in der Liste mit dem neuen Wert überschrieben werden.

Listen mit unveränderbaren Elementen#

Angenommen wir wir haben eine Liste money, welche 3 Elemente des Typs int enthält. Diese erstelle ich im Folgenden:

money = [100, 200, 500]

Nun wollen wir die 3 Elemente innerhalb der Liste money jeweils um den Wert 50 erhöhen. Probieren wir es mal mit folgendem For-Loop:

for m in money:
    m = m + 50

Die Hoffnung ist nun, dass sich jedes Element der Liste money um den Wert 50 erhöht hat. Schauen wir mal nach:

money
[100, 200, 500]

Das hat leider nicht geklappt. Wir haben zwar innerhalb des For-Loops die Schleifenvariable m jeweils um 50 erhöht, allerdings haben wir die Elemente der Liste nicht überschrieben. Das liegt daran, dass die Elemente der Liste money unveränderbare Objekte sind. Verändern wir die Schleifenvariable indem wir diese mit einem neuen Wert überschreiben, dann ändern wir nicht das Objekt, das in der Liste liegt, sondern weisen der Schleifenvariable ein neues Objekt zu. Damit kappen wir gleichzeitig die Verbindung zwischen der Schleifenvariable und dem Objekt, das in der Liste liegt und wir eigentlich ja verändern wollten.

Um unveränderbare Objekte innerhalb von Listen in einem For-Loop zu “ändern”, müssen wir diese direkt in der Liste überschreiben. Um das zu tun, müssen wir innerhalb des For-Loops per Listenindizierung direkt auf die Position des Elements in der Liste zugreifen und für diese Position ein neues Objekt einfügen und somit das vorherige Objekt überschreiben. Um Listenindizierung zu nutzen, brauchen wir die entsprechenden Indizes der zu verändernden Elemente in der Liste, die wir uns mit range() und len() produzieren. Im Folgenden greife ich innerhalb des For-Loops per Indizierung nacheinander auf die Elemente des For-Loops zu und überschreibe jedes Element in der Liste mit einem neuen Wert bzw. ich füge für jede Position der Liste ein neues Objekt ein, das ich mir aber mithilfe des vorherigen Objektes auf dieser Position berechne.

for i in range(len(money)):
    money[i] = money[i] + 50

Werfen wir nun einen Blick auf die Liste money, sehen wir, dass sich die Elemente nun wirklich verändert haben.

money
[150, 250, 550]

Wir merken uns: Sind die Elemente/Objekte, auf die die Schleifenvariable nach und nach zeigt, unveränderbar, dann können wir diese nicht direkt über die Schleifenvariable selbst ändern, sondern müssen per Listenindizierung auf die Elemente/Objekte zugreifen und diese überschreiben.

Listen mit veränderbaren Elementen#

Das Vorgehen von oben müssen wir allerdings nicht jedes mal so machen, sondern eben nur, wenn wir eigentlich unveränderbare Objekte innerhalb einer Liste in einem For-Loop “verändern” wollen. Im Falle von sogenannten veränderbaren Objekten müssen wir diesen Umweg über die Listenindizierung allerdings nicht nehmen, sondern können die Schleifenvariable so behandeln als wäre es das Objekt selbst: Jede Veränderung an der Schleifenvariable ist eine Veränderung am eigentlichen Objekt in der Liste, über die wir loopen.

Schauen wir uns das Ganze anhand eines Beispieles bei der wir den Inhalt einer Liste von Listen (also Listen) innerhalb eines For-Loops verändern wollen. Wie gesagt, eine Liste ist ein veränderbares Objekt. Dadurch können wir in einem For-Loop diesmal direkt nacheinander auf den Inhalt der geschachtelten Liste zugreifen und diesen direkt anhand der Schleifenvariable verändern. Denn der Inhalt der geschachtelten Liste sind Listen und Listen sind veränderbare Objekte.

Hier erstelle ich zunächst die geschachtelte Liste:

population = [["Hartmut"], ["Anna"], ["Michael"]]
population
[['Hartmut'], ['Anna'], ['Michael']]

Nun gehe ich per For-Loop diese geschachtelte Liste durch. Der For-Loop weist nacheinander der Schleifenvariable agent ein Element (eine Liste) der geschachtelten Liste zu. Diese jeweils durch die Schleifenvariable repräsentierte Liste kann ich innerhalb des For-Loops direkt verändern. Im Beispiel nutze ich die Methode append(), um jeder Sub-Liste der geschachtelten Liste eine 100 anzuhängen.

for agent in population:
    agent.append(100)

Wenn wir uns nun die Variable population anschauen, dann sehen wir, dass sich tatsächlich die damit beschriftete Liste bzw. der Inhalt dieser geschachtelten Liste verändert hat:

population
[['Hartmut', 100], ['Anna', 100], ['Michael', 100]]