присвоение значения итерируемой переменной Python

Этот код работает как надо:

ak_1 = np.zeros((2, 2))
ak_2 = np.zeros((2, 2))

for  kk in [ak_1, ak_2]:
    print('ak1 old: \n',ak_1)
    print('ak2 old: \n',ak_2)

    kk[0] = [1, 1]
    print('write this row:\n',kk[0])

    print('ak1 new: \n',ak_1)
    print('ak2 new: \n',ak_2)
    print()
    print()

print()        
print('ak1 in the end: \n',ak_1)
print('ak2 in the end: \n',ak_2)

вывод:

ak1 old: 
 [[0. 0.]
 [0. 0.]]
ak2 old: 
 [[0. 0.]
 [0. 0.]]
write this row:
 [1. 1.]
ak1 new: 
 [[1. 1.]
 [0. 0.]]
ak2 new: 
 [[0. 0.]
 [0. 0.]]


ak1 old: 
 [[1. 1.]
 [0. 0.]]
ak2 old: 
 [[0. 0.]
 [0. 0.]]
write this row:
 [1. 1.]
ak1 new: 
 [[1. 1.]
 [0. 0.]]
ak2 new: 
 [[1. 1.]
 [0. 0.]]

ak1 in the end: 
 [[1. 1.]
 [0. 0.]]
ak2 in the end: 
 [[1. 1.]
 [0. 0.]]

но этот код не работает:

a = 0
b = 0

for xx in [a,b]:
    xx = 1

print(a, b)

на выходе получаю (0,0) почему?


Ответы (2 шт):

Автор решения: Xander

В первом случае вы берёте переменную цикла, и обращаетесь к её элементам, меняя их.

А во втором случае вы берёте переменную цикла, ничего не делаете с ней, но под этим именем сохраняете совсем другое значение. Оригинальные элементы остаются неизменными.

→ Ссылка
Автор решения: prupru

вроде стало понятно. мне кажется, в случае с массивами работает также как в этом случае:

x = [1]
y=x
print(y)
x[0]=2
print(y)

вывод: [1]
[2]

То есть переменной присваивается ссылка на массив, затем эта же ссылка присваивается итератору. Далее объект по ссылке изменяется, затем когда мы выводим переменную, она ссылается на все тот же массив, который был изменен. В случае с float объект по ссылке не изменяется, а создается новый объект, ссылка на который присваивается итератору.

→ Ссылка