-1

I am trying to change only one out of three identical dictionary in my list using a for loop to slice out exactly the 2nd dictionary on my list. But somehow the values of all the 3 dictionaries in my list change as if i did not slice it correctly. What am I missing?

Code:

p1 = {
    'fn': 'kan',
    'ln': 'go',
    'icolor': 'brown',
    'age': 3.5,
    'location': 'CA',
    }


p_list = []

for i in range(0,3):
    p_list.append(p1)


for p_info in p_list[1:2]:
    if p_info['fn'] == 'kan':
        p_info['fn'] = 'ad'
        p_info['ln'] = 'se'
        p_info['icolor'] = 'brown'
        p_info['age'] = 30
        p_info['location'] = 'CN'

print(p_list)

Actual Output:

[{'fn': 'ad', 'ln': 'se', 'icolor': 'brown', 'age': 30, 'location': 'CN'}, {'fn': 'ad', 'ln': 'se', 'icolor': 'brown', 'age': 30, 'location': 'CN'}, {'fn': 'ad', 'ln': 'se', 'icolor': 'brown', 'age': 30, 'location': 'CN'}]

Expected Output:

[{'fn': 'kan', 'ln': 'go', 'icolor': 'brown', 'age': 3.5, 'location': 'CA'}, {'fn': 'ad', 'ln': 'se', 'icolor': 'brown', 'age': 30, 'location': 'CN'}, {'fn': 'kan', 'ln': 'go', 'icolor': 'brown', 'age': 3.5, 'location': 'CA'}]
Adhi
  • 1
  • 1
  • 1
    `p_list` contains three _references_ to the same dictionary object. When one changes, they all change, because they're the same object. – John Gordon May 21 '22 at 19:02
  • Does this answer your question? [Changing one dict changes all dicts in a list of dicts](https://stackoverflow.com/questions/57990256/changing-one-dict-changes-all-dicts-in-a-list-of-dicts) – Nick May 21 '22 at 22:44

1 Answers1

0

It is because all the three elements of the list are the same reference objects. Any changes made to one dictionary will change the elements in all the three dictionaries. Example:

If there's a dictionary: a={'x':1,'y'=2} And there is a variable b which has exact value of a: b=a

Any changes made in a will effect b also and vice versa. But if you want to keep them independent, we need to create copies of it by copy() method. If you type:

b=a.copy()

Now any changes made will not effect the other. The same goes with your code. We need to create three copies of your dictionary and you can do it by the command:

p_list = [p1.copy() for i in range(3)]

So your new code would be:

p1 = {
    'fn': 'kan',
    'ln': 'go',
    'icolor': 'brown',
    'age': 3.5,
    'location': 'CA',
    }


p_list = [p1.copy() for i in range(3)]



for p_info in p_list[1:2]:
    if p_info['fn'] == 'kan':
        p_info['fn'] = 'ad'
        p_info['ln'] = 'se'
        p_info['icolor'] = 'brown'
        p_info['age'] = 30
        p_info['location'] = 'CN'

print(p_list)
  • Thank you so much. This is very helpful. So is it right to say that the 'append()' method I used to create the p_list did not copy the dictionary but instead just set the p_list[1] and p_list[2] element to p1? – Adhi May 21 '22 at 19:33
  • Yes you can say that. The point is that the values of each index of the list is the same object. Any changes in one will reflect in all. If you found it helpful then you can cheer it up by upvoting it –  May 21 '22 at 19:38
  • Thanks mate. I am new so it is not recording my upvotes. +1 – Adhi Sep 20 '22 at 19:06