Невозможно изменить элементы списка в цикле Python
При переходе по списку в Python мне не удалось изменить элементы без понимания списка.
Для справки:
li = ["spam", "eggs"]
for i in li:
i = "foo"
li
["spam", "eggs"]
li = ["foo" for i in li]
li
["foo", "foo"]
Итак, почему я не могу изменять элементы через цикл в Python? Там определенно чего-то не хватает, но я не знаю, что. Я уверен, что это дубликат, но я не мог найти вопрос об этом, и если есть ссылка, этого было бы более чем достаточно. Заранее благодарю вас!
Ответы
Ответ 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'