Python seltsames Verhalten in for-Schleife oder Listen

8

Ich entwickle gerade ein Programm in Python und habe gerade bemerkt, dass etwas mit der foreach-Schleife in der Sprache oder vielleicht der Listenstruktur nicht stimmt. Ich werde nur ein generisches Beispiel meines Problems zur Vereinfachung geben, da ich das gleiche fehlerhafte Verhalten sowohl in meinem Programm als auch in meinem generischen Beispiel bekomme:

%Vor%

Nun, das Problem hier ist einfach, ich dachte, dass dieser Code alle Elemente aus einer Liste entfernen sollte. Nun, das Problem ist, dass ich nach der Ausführung immer 2 Elemente in der Liste bekomme.

Was mache ich falsch? Danke für die Hilfe im Voraus.

Bearbeiten: Ich möchte keine Liste leeren, dies ist nur ein Beispiel ...

    
rogeriopvl 12.04.2009, 20:30
quelle

6 Antworten

30

Dies ist ein gut dokumentiertes Verhalten in Python, dass Sie die Liste, die durchlaufen wird, nicht ändern sollten. Versuchen Sie es stattdessen:

%Vor%

Das [:] gibt ein "Segment" von x zurück, das zufällig alle seine Elemente enthält und somit eine Kopie von x ist.

    
Chris Jester-Young 12.04.2009, 20:36
quelle
11

Wenn Sie ein Element löschen und die for-Schleife in den nächsten Index wechselt, überspringen Sie ein Element.

Mach es rückwärts. Oder geben Sie bitte Ihr wirkliches Problem an.

    
Erik 12.04.2009 20:37
quelle
4

Ich denke, im Großen und Ganzen, wenn Sie schreiben:

%Vor%

Unter der Haube macht Python so etwas:

%Vor%

Wenn Sie lst.remove(x) für den Schleifenkörper einfügen, können Sie dann vielleicht sehen, warum Sie das Ergebnis erhalten, das Sie tun?

Im Wesentlichen verwendet Python einen beweglichen Zeiger, um die Liste zu durchlaufen. Der Zeiger beginnt mit dem Zeigen auf das erste Element. Dann entfernen Sie das erste Element und machen das zweite Element zum neuen ersten Element. Dann bewegt sich der Zeiger zum neuen zweiten - vorher dritten - Element. Und so weiter. (Es könnte klarer sein, wenn Sie [1,2,3,4,5] anstelle von [1,2,2,2,2] als Beispielliste verwenden)

    
John Fouhy 13.04.2009 02:43
quelle
3

Warum benutzt du nicht einfach:

%Vor%

Wahrscheinlich weil Sie das gleiche Array ändern, über das Sie iterieren.

Versuchen Sie Chris-Jester Youngs Antwort, wenn Sie das Array auf Ihre Art löschen möchten.

    
fluffels 12.04.2009 20:38
quelle
1

Ich stimme John Fouhy bezüglich der Unterbrechungsbedingung zu. Das Durchlaufen einer Kopie der Liste funktioniert für die Methode remove (), wie Chris Jester-Young vorgeschlagen hat. Aber wenn man bestimmte Elemente poppen () muss, funktioniert das Iterieren in umgekehrter Reihenfolge, wie Erik erwähnte, in welchem ​​Fall die Operation an Ort und Stelle durchgeführt werden kann. Zum Beispiel:

%Vor%


oder mit xrange:

%Vor%     
eryksun 07.11.2009 17:12
quelle
1

Ich weiß, das ist ein alter Post mit einer akzeptierten Antwort, aber für diejenigen, die vielleicht noch kommen ...

Einige frühere Antworten haben gezeigt, dass es eine schlechte Idee ist, während der Iteration eine Iteration zu ändern. Aber um zu zeigen, was passiert ...

%Vor%

Hoffentlich hilft das Visuelle zu klären.

    
user1801810 05.08.2016 22:01
quelle

Tags und Links