wake-up-neo.net

Ändern der Liste während der Iteration

l  = range(100)                         
for i in l:                         
    print i,                         
    print l.pop(0),                  
    print l.pop(0)

Der obige Python-Code gibt die Ausgabe völlig anders als erwartet. Ich möchte Elemente überlaufen lassen, sodass ich einen Artikel überspringen kann.

Bitte erkläre.

49
Xolve

Ich bin schon einmal von einem "cleveren" Code (einer anderen Person) gebissen worden, der versucht, eine Liste zu modifizieren, während er durchläuft. Ich beschloss, dass ich es unter keinen Umständen tun würde.

Mit dem Slice-Operator mylist[::3] können Sie zu jedem dritten Element in Ihrer Liste springen.

mylist = [i for i in range(100)]
for i in mylist[::3]:
  print(i),

Andere Punkte zu meinem Beispiel beziehen sich auf die neue Syntax in python 3.0

  • Ich benutze ein Listenverständnis, um mylist zu definieren, weil es in Python 3.0 funktioniert (siehe unten).
  • print ist eine Funktion in Python 3.0

Python 3.0 range () verhält sich jetzt wie xrange (), mit dem es sich verhält, außer dass es mit Werten beliebiger Größe funktioniert. Letzteres existiert nicht mehr.

40
Ewan Todd

Ändern Sie niemals den Container, in dem Sie eine Schleife ausführen, da die Iteratoren auf diesem Container nicht über Ihre Änderungen informiert werden. Wie Sie bemerkt haben, führt dies sehr wahrscheinlich zu einer sehr unterschiedlichen und/oder falschen Schleife. Im Normalfall hilft es, eine Kopie des Containers zu wiederholen, aber in Ihrem Fall ist es klar, dass Sie nicht das wollen, da der Container nach 50 Abschnitten der Schleife leer ist und wenn Sie dann erneut versuchen, zu poppen Sie erhalten eine Ausnahme.

Was ist ABER klar ist, welches Verhalten wollen Sie erreichen, wenn überhaupt ?! Vielleicht können Sie Ihre Wünsche mit einer while... ausdrücken?

i = 0
while i < len(some_list):
    print i,                         
    print some_list.pop(0),                  
    print some_list.pop(0)
49
Alex Martelli

Als Faustregel gilt, dass Sie eine Sammlung/ein Array/eine Liste nicht ändern, während Sie darüber iterieren. 

Verwenden Sie eine sekundäre Liste, um die Elemente zu speichern, die Sie bearbeiten möchten, und führen Sie diese Logik nach der ersten Schleife in einer Schleife aus.

11
Paul Sasik

Versuche dies. Dadurch wird vermieden, dass Sie etwas verändern, das Sie durchlaufen, was in der Regel ein Codegeruch ist.

for i in xrange(0, 100, 3):
    print i

Siehe xrange .

8
Hank Gay

Verwenden Sie eine while-Schleife, die die Richtigkeit des Arrays überprüft:

while array:
    value = array.pop(0)
    # do some calculation here

Und es sollte es ohne Fehler oder lustiges Verhalten tun.

8
Eugene Eeo

Ich denke, das ist, was Sie wollen:

l  = range(100)  
index = 0                       
for i in l:                         
    print i,              
    try:
        print l.pop(index+1),                  
        print l.pop(index+1)
    except:
        pass
    index += 1

Es ist sehr praktisch zu codieren, wenn die Anzahl der zu löschenden Elemente eine Laufzeitentscheidung ist ... __, aber es läuft sehr schlecht und der Code ist schwer zu warten.

1
York Chang

Diese Slice-Syntax erstellt eine Kopie der Liste und macht, was Sie möchten:

l  = range(100)  
for i in l[:]:  
    print i,  
    print l.pop(0),  
    print l.pop(0)
0
thethinman