ссылки и итераторы python в циклах [дубликаты]

Я бы столкнулся с тонкой ошибкой в ​​задействованном скрипте Python. В основном то, что пошло не так, выглядит так

def inc(x):
    return x+1

a = 1
b = 2
c = 3

for x in [a,b]:
    print(id(x), id(a), id(b))

for x in [a,b]:
    x = inc(x)
c = inc(c)

print(a,b,c)

Как показывает первый цикл for, итератор x получает ссылку на текущую переменную. Тем не менее, когда мы присваиваем значение этому итератору, переменная pointee(referencee) не меняется. Я действительно не ожидал такого поведения, это не питон, не так ли? Может ли кто-нибудь пролить свет на это?


person Juan Chô    schedule 15.10.2020    source источник
comment
a и b не изменяемы, поэтому вы не можете их изменить. Даже если вы измените ничего не произойдет   -  person deadshot    schedule 15.10.2020
comment
Не совсем понятно, что вы считаете ошибкой. Возможно, посмотрите stackoverflow .com/questions/986006/   -  person buran    schedule 15.10.2020


Ответы (1)


Для вашего первого цикла вы печатаете идентификаторы x, a, b. x - это локальная переменная, а не a или b. Хотя он содержит ссылку на тот же номер, это не тот же экземпляр ссылки, что и a или b. Целые числа неизменяемы в python. Когда вы выполняете что-то вроде x = x + 1, вы не меняете значение по ссылке, а меняете ссылку, чтобы указать на новое значение.

Кроме того, имейте в виду, что в Python целые числа от -5 до 255 вычисляются еще до того, как на них ссылаются. Это одна из многих оптимизаций Python.

Таким образом, на первой итерации x содержит значение a, а поскольку оно равно 1, оно уже вычислено, и они указывают на одно и то же место в памяти. На второй итерации x указывает на то же значение, что и b. Но ни в том, ни в другом случае сама ссылка не является одной и той же.

Если бы ваши a, b, c были изменчивыми, как списки или словари, вы бы наблюдали другое поведение. Вероятно, тот, который вы ожидаете.

person go2nirvana    schedule 15.10.2020
comment
Это неправда, это происходит и с изменяемыми вещами, просто попробуйте! Возьми список и увидишь. Это не имеет ничего общего с целым числом: это происходит с другими переменными. Моя первоначальная проблема была с изменчивыми массивами numpy. - person Juan Chô; 15.10.2020
comment
Если вы переназначите изменяемую переменную - этого не произойдет, но если вы, скажем, дополните список - это произойдет. - person go2nirvana; 15.10.2020