2013-10-10 12 views
19

Podczas zapętlania listy w języku Python nie mogłem modyfikować elementów bez zrozumienia list. Dla porównania:Nie można modyfikować elementów listy w pętli Python

li = ["spam", "eggs"] 
for i in li: 
    i = "foo" 

li 
["spam", "eggs"] 

li = ["foo" for i in li] 
li 
["foo", "foo"] 

Więc dlaczego nie mogę modyfikować elementy za pomocą pętli w Pythonie? Jest zdecydowanie coś, czego mi brakuje, ale nie wiem co. Jestem pewien, że jest to duplikat, ale nie mogłem znaleźć odpowiedzi na to pytanie, a jeśli istnieje link, byłoby to więcej niż wystarczające. Z góry dziękuję!

+3

See [to] (http://stackoverflow.com/questions/4081217/how-to-modify-list-entries-during-for-loop), [to] (http: // stackoverflow. com/questions/1637807/modifying-list-while-iterating) – devnull

Odpowiedz

21

Ponieważ droga for i in li działa to mniej więcej tak:

for idx in range(len(li)): 
    i = li[idx] 
    i = 'foo' 

Więc jeśli przypisać cokolwiek i, to nie będzie miało wpływu li[idx].

Rozwiązaniem jest albo tego, co zostało zaproponowane, lub zapętlenie poprzez indeksy:

for idx in range(len(li)): 
    li[idx] = 'foo' 

lub korzystają enumerate:

for idx, item in enumerate(li): 
    li[idx] = 'foo' 
+0

Zapętlenie przez indeksy nie działa dla mnie, używam Pythona 3.6. Nieważne. Używam plasterka, dlatego. – Valachio

8

W rzeczywistości z listowego nie modyfikują liście, Tworzy nową listę, a następnie przypisuje ją do zmiennej, która zawierała poprzednią.

W każdym razie, kiedy robisz for i in li otrzymujesz kopię każdej wartości li w zmiennej i, nie uzyskać odniesienie do pozycji, w li, więc nie modyfikując dowolną wartość w li.

Jeśli chcesz zmodyfikować swoją listę można to zrobić z enumerate:

>>> li = ["spam", "eggs"] 
>>> for i,_ in enumerate(li): 
     li[i] = "foo" 
>>> li 
['foo', 'foo'] 

lub z xrange (w Pythonie 2.7, użyj zakres w Pythonie 3):

>>> for i in xrange(len(li)): 
     li[i] = "foo" 
>>> li 
['foo', 'foo'] 

lub przy ze zrozumieniem listy, które pokazałeś w swoim pytaniu.

1

jestem w stanie zmodyfikować listę podczas zapętlenie:

lst = range(10) // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

for i, elem in enumerate(lst): 
    lst[i] = 0 // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
1

for element in li - zwraca ci kopię elementu, a nie sam element.

rozwiązanie dla przypadku byłoby:

for i in range(len(li)): 
    li[i] = 'foo' 
1

Może wykorzystujące słowniki mogą być pomocne.

>>> li = {0: "spam", 1:"eggs"} 
    for k, v in li.iteritems(): 
     li[k] = "foo" 

>>> li 
{0: 'foo', 1: 'foo'} 
Powiązane problemy