Работает ли Python для циклов по ссылке?

При использовании цикла for в Python для перебора элементов в списке изменится item (ниже), измените соответствующий элемент в items?

for item in items:
    item += 1

Будет ли каждый элемент в элементах увеличиваться или оставаться таким же, как перед циклом?

[Примечание: меня интересовали бы Python 2.7 и 3.x]

Ответ 1

Нет, переменные в Python не являются указателями.

Вместо этого они ссылаются на объекты в куче, а присвоение переменной не изменяет ссылочный объект, а переменную. Переменные и объекты похожи на ярлыки, привязанные к воздушным шарам; назначение вместо этого присваивает метку другому шару.

Смотрите этот мой предыдущий ответ, чтобы изучить эту идею воздушных шаров и надписей немного больше.

Тем не менее, некоторые типы объектов реализуют специфическое поведение добавления на месте. Если объект изменен (сам воздушный шар может измениться), то добавление на месте может быть интерпретировано как мутация вместо назначения.

Итак, для целых чисел item += 1 действительно то же самое, что и item = item + 1, потому что целые числа неизменны. Вы должны создать новый целочисленный объект и привязать метку item к этому новому объекту.

Списки с другой стороны, являются изменяемыми и lst += [other, items] реализуется как lst.__iadd__([other, items]) и который изменяет сам шар lst. Назначение все еще имеет место, но это переопределение одного и того же объекта, так как метод .__iadd__() просто возвращает self вместо нового объекта. Мы заканчиваем тем, что привязываем ярлык к тому же воздушному шару.

Цикл просто дает вам ссылку на следующий элемент в списке на каждой итерации. Он не позволяет вам изменять исходный список (это просто еще один набор ярлыков шаров); вместо этого он дает вам новый ярлык каждому из содержащихся элементов.

Ответ 2

Ну, это действительно зависит от элементов.

Возьмем следующий случай:

class test():
    pass

a = test()
a.value = 1

b = test()
b.value = 2

l = [a,b]

for item in l:
    item.value += 1

for item in l:
    print item.value

>>> 
2
3

и в этом случае:

l2 = [1,2,3]

for item in l2:
    item += 1

for item in l2:
    print item

>>> 
1
2
3

Итак, как вы можете видеть, вам нужно понять указатели как Martijn.