Code
Initially, I have some instances of classes stored in a dictionary, each with some initialized attribute.
class A:
def __init__(self):
self.foo = 'bar'
my_dict = {}
for i in range(3):
my_dict[i] = A()
Now, I call a function on a dictionary value, my_dict[1]
, say, wanting to change the .foo
attributes of all values in the dictionary, except that of my_dict[1]
, which I would like to change differently.
def outer(v):
for k,v in my_dict.items():
my_dict[k].foo = 'nada'
v.foo = 'sand'
my_entry = my_dict[1]
outer(my_entry)
print(list((k,v.foo) for (k,v) in my_dict.items()))
However, the third line under outer(v)
ends up changing my_dict[2].foo
instead.
Problem
Consider the three lines in the function outer(v)
, and the output from the print(...)
.
- Without first two lines, gives
[(0, 'bar'), (1, 'sand'), (2, 'bar')]
as expected. - Without third line, gives
[(0, 'nada'), (1, 'nada'), (2, 'nada')]
as expected. - However, with all three lines, gives
[(0, 'nada'), (1, 'nada'), (2, 'sand')]
.
This suggests the variable v has been 'stuck' at index 2, following exit from for-loop. Why does Python do this?
Background
This problem caused a huge hold-up in a larger program I was making. This is my first attempt at asking a question on Stack Overflow by making a minimal, reproducible example. Any advice on how to make the question clearer or better is very much appreciated. Thank you.