-2

I have a question about dicts, there is a code like below. I have no idea why variable 'a' is changed.

b = []
a = [(1, {"name":"test1"}), (2, {"name":"test2"})]


for i in a:
        x,  y = i
        x["name"] = "test3"
        b.append(x)

After above codes, a = [(1, {"name":"test3"}), (2, {"name":"test3"})] i think i didn't understand logic of dicts. Can you explain me how this happen? And i dont want main list to change, is there another way?

jizhihaoSAMA
  • 12,336
  • 9
  • 27
  • 49
Kirchoff
  • 19
  • 3

2 Answers2

1

Your code needs some improvements. Check below:

b = []
a = [(1, {"name":"test1"}), (2, {"name":"test2"})]


for i in a:
        x = i[0] #we declare x and y seperately because we want y to be declared as a copy of the dict
        y=i[1].copy() #you must assign a copy of the dict so that changes on y will not applied to original dict
        y["name"] = "test3"
        b.append(x)
IoaTzimas
  • 10,538
  • 2
  • 13
  • 30
1

The problem is that you always manipulate the very same dict, under different names, so any change you make to it is reflected in all the places you refer to it.

You need to create a new dict. As your dict values are immutable, a simple shallow copy is enough (have a look at copy.deepcopy otherwise, that might be needed then - you can find more in-depth info in this question).

So, your code could be:

b = []
a = [(1, {"name":"test1"}), (2, {"name":"test2"})]


for val, dct in a:
        new_dict = dct.copy()
        new_dict["name"] = "test3"
        b.append(new_dict)
        
print(b)
# [{'name': 'test3'}, {'name': 'test3'}]
print(a)
# [(1, {'name': 'test1'}), (2, {'name': 'test2'})]

As a side note, I unpacked the tuple directly in the loop, and gave your variables more meaningful names...

Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50