Подтвердить что ты не робот

Невозможно изменить элементы списка в цикле Python

При переходе по списку в Python мне не удалось изменить элементы без понимания списка. Для справки:

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

li
["spam", "eggs"]

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

Итак, почему я не могу изменять элементы через цикл в Python? Там определенно чего-то не хватает, но я не знаю, что. Я уверен, что это дубликат, но я не мог найти вопрос об этом, и если есть ссылка, этого было бы более чем достаточно. Заранее благодарю вас!

4b9b3361

Ответ 1

Поскольку способ for i in li работает примерно так:

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

Итак, если вы назначаете что-либо для i, это не повлияет на li[idx].

Решение - это то, что вы предложили, или цикл по индексам:

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

или используйте enumerate:

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

Ответ 2

Фактически, при понимании списка вы не изменяете список, вы создаете новый список и затем назначаете его переменной, содержащей предыдущую.

В любом случае, когда вы делаете for i in li, вы получаете копию каждого значения li в переменной i, вы не получаете ссылку на позицию в li, поэтому вы не изменяете никаких значение в li.

Если вы хотите изменить свой список, вы можете сделать это с помощью enumerate:

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

или с помощью xrange (в Python 2.7 используйте диапазон в python 3):

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

или со списком, которое вы указали в своем вопросе.

Ответ 3

Я могу изменить список во время цикла:

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]

Ответ 4

Возможно, использование словарей может быть полезным.

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

>>> li
{0: 'foo', 1: 'foo'}

Ответ 5

for element in li - возвращает вам копию элемента, а не самого элемента.

Решение для вашего дела будет:

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