как работает for loop в python
Подскажите пожалуйста "guitar" является переменной или это строка? Если она является переменной то почему я не могу придать ей новое значение и изменить список таким способом? Я знаю как решить эту задачу другим способом, но не могу понять почему данный способ не работает.
guitars = ['phil pro', 'epiphone', 'gibson']
for guitar in guitars:
guitar = 'electric ' + guitar
# print(guitar) -- если выводить отсюда, то все выводится как мне надо, но список при этом не изменяется
print(guitars)
output:
['phil pro', 'epiphone', 'gibson']
Ответы (3 шт):
Нужно менять сам список, через индексы:
guitars = ['phil pro', 'epiphone', 'gibson']
for i, guitar in enumerate(guitars):
guitars[i] = 'electric ' + guitar
print(guitars)
# ['electric phil pro', 'electric epiphone', 'electric gibson']
При итерации цикла for guitar in guitars: будет создана переменная guitar, в которую будут помещаться значения, а такая операция guitar = 'electric ' + guitar установит новое значение в переменную, старое не будет меняться
Строки вообще неизменяемый тип, поэтому поменять объект строки не получится - только новый создать
Но если хочется, то можно сделать объект и его менять:
from dataclasses import dataclass
@dataclass
class Guitar:
name: str
guitars = [Guitar('phil pro'), Guitar('epiphone'), Guitar('gibson')]
for guitar in guitars:
guitar.name = 'electric ' + guitar.name
print(guitars)
# [Guitar(name='electric phil pro'), Guitar(name='electric epiphone'), Guitar(name='electric gibson')]
for guitar in guitars:
При итерировании через for переменной guitar присваиваются по очереди значения из списка guitars. Но у этих значений и у этой переменной нет никакой обратной связи со списком, который перебирается. Как бы вы не меняли переменную цикла, эти никак не отразится на перебираемом списке.
В принципе, это не только в Питоне так, а, кажется, во всех языках. Переменная цикла - это просто переменная, которой что-то присваивается, а не ссылка на элементы перебираемой коллекции.
guitar - это переменная. На каждой итерации в ней оказывается содержимое очередного элемента списка. Для простоты восприятия считайте, что это копия. И когда вы присваиваете новое значение этой переменной, то это значение присваивается только ей, и никуда больше.
В этом можно удостовериться самостоятельно:
guitars = ['phil pro', 'epiphone', 'gibson']
for i, guitar in enumerate(guitars):
print(i, "До :", id(guitar), id(guitars[i]))
guitar = 'electric ' + guitar
print(i, "После:", id(guitar), id(guitars[i]))
0 До : 140048368419120 140048368419120
0 После: 140048300344144 140048368419120
1 До : 140048300509296 140048300509296
1 После: 140048300344144 140048300509296
2 До : 140048300508464 140048300508464
2 После: 140048369136624 140048300508464
Как можно заметить, до присваивания нового значения переменная и соответствующее значение из списка эквивалентны, т.е. указывают на одно и то же значение в памяти. По после присваивания они уже указывают на разные значения.
Для модификации элемента списка следует обращаться к нему непосредственно по его индексу: guitars[i].