2016-07-19 11 views
0

Ich habe einen Python-Code, der die Liste während der Iteration ändert. Warum iteriert es 5 mal? Ich erwarte, dass es gemäß der neuen Liste iterieren sollte.Iterate Liste beim Zuweisen neuer Werte

Was ist "for i in l" darunter? Warum hat es nichts mit I während der Iteration zu tun?

Wenn l nicht geändert wird, warum nach der Schleife ist es leer?

cnt = 4 
def print_list(): 
    global cnt 
    l=[1, 2, 3, 4, 5] 
    for i in l: # why it iterates 5 times? 
     print "iteration ", i 
     l = range(1, cnt) # new assignment 
     print l 
     cnt-=1 
    print "after loop l is ", l # after loop, l is empty 

drucken Ergebnis:

iteration 1 
[1, 2, 3] 
iteration 2 
[1, 2] 
iteration 3 
[1] 
iteration 4 
[] 
iteration 5 
[] 
after loop l is [] 

EDIT: aus den unten Antworten, ich verstehe jetzt:

  1. in Python, l nach Zuordnung zu einem anderen Objekt bezieht;
  2. Originalobjekt, das sehr am Anfang von l verwiesen wird, wird nicht geändert.
+5

"Ich habe einen Python-Code, der die Liste während der Iteration ändert" - *** tu das nicht ***. Außerdem ändern Sie die Liste nicht. Sie ändern die Variable "l", aber die Schleife beachtet das nicht mehr. – user2357112

+0

Das Ändern der Liste in Python während der Iteration ist akzeptabel, wenn Sie die Größe nicht ändern und wissen, was Sie tun. – Rockybilly

+0

@ user2357112, wenn ich nicht l ändere, warum nach der Schleife ist es leer? – pepero

Antwort

1

Innerhalb der for-Schleife werden die Neuzuweisung Sie die Variable von l auf eine neue Liste - aber nicht die ursprüngliche l Umstellen der Sie Iterieren noch.

Hier ist ein prägnantes Beispiel diese Situation zeigt, wo l jetzt my_object genannt wird, und wo my_object als list beginnt und mit sinnlose Zeichenfolge zugewiesen, die nicht die Iteration beeinflussen:

random_things = [ 
    "dog", "cat", "fish", "bird", "bug" 
] 

my_object = xrange(len(random_things)) 
orig_id = id(my_object) 
for i in my_object: 
    if i == 0: 
     first_iter_id = id(my_object) 
    print orig_id == id(my_object), 

    # At this point, my_object is 
    # reassigned and has no influence on 
    # the my_object that is be iterated over 
    my_object = random_things[i] 
    print i, my_object 

print "Original ID == FirstIter ID? {0}".format(orig_id == first_iter_id) 
print "Original ID == LastIter ID? {0}".format(orig_id == id(my_object)) 

Ausgang:

True 0 dog 
False 1 cat 
False 2 fish 
False 3 bird 
False 4 bug 
Original ID == FirstIter ID? True 
Original ID == LastIter ID? False 

In diesem Beispiel können Sie sehen, wie die id von my_object bei der ersten Iteration ist immer noch gleich dem Original id von my_object; aber danach weisen Sie my_object neu zu, und es verweist auf ein neues Objekt im Speicher.

Nur weil wir den Namen my_object einem neuen Objekt im Speicher zuweisen, heißt das nicht, dass wir den Wert des ursprünglichen Objekts mutieren, über das wir immer noch iterieren.

Um dies zu sehen, merken, wie first_iter_id zu orig_id gleich ist, nachdem die Schleife abgeschlossen ist - das becasue first_iter_id zugewiesen wurde, bevor wir my_object an dieser ersten Iteration überschrieben.

+0

Ich würde empfehlen, den Flaum aus dem Code in der Antwort auszuschneiden, können Sie das Problem in einer viel kürzeren Schleife demonstrieren –

+0

@RyanHaining Ich stimme zu, und wird das Beispiel vereinfachen, wenn ich zusätzliche Zeit bekomme. Ich hoffe, das OP wird dies in der Zwischenzeit informativ finden. – JohnZ

1

Sie sind nicht wirklich die Liste zu ändern, indem

l = range(1, cnt) 

zuweisen Wenn Sie vor Sprachen C-Typ untersucht, verhält sich diese Zuordnung wie eine andere Definition in einem anderen Rahmen. Außerdem wird die Liste zwischengespeichert, bevor die for-Schleife gestartet wird, um Wiederholungen zu vermeiden. Beispiel:

for i in range(10): 
    #pass 

erstellt keine range(10) Liste zehn Mal.Die erste wird gespeichert, so dass sie während der gesamten Iteration verwendet werden kann.

Wenn Sie die Liste wirklich ändern möchten, müssen Sie Operationen ausführen, die keine neue Liste im Speicher erstellen. Wie,

können Sie diese selbst auf Ihrer Schleife versuchen und das Ergebnis herausfinden.