0

I am trying to use a dictionary (created by reading the content of a first file) to modify the content of an array(created by reading the content of a second file) in order to return as many modified arrays as their are keys in the dictionary with the modification corresponding the position and change in the original array indicated in the values for each key.

From a minimal example, if my dictionary and my list are:

change={'change 1': [(1, 'B'), (3, 'B'), (5, 'B'), (7, 'B')], 'change 2': [(2, 'B'), (4, 'B'), (6, 'B')]}
s=['A', 'A', 'A', 'A', 'A', 'A', 'A']

Then, I would like my code to return two lists:

['B', 'A', 'B', 'A', 'B', 'A', 'B']
['A', 'B', 'A', 'B', 'A', 'B', 'A']

I tried to code this in python3:

change={'change 1': [(1, 'B'), (3, 'B'), (5, 'B'), (7, 'B')], 'change 2': [(2, 'B'), (4, 'B'), (6, 'B')]}
s=['A', 'A', 'A', 'A', 'A', 'A', 'A']
for key in change:
    s1=s
    for n in change[key]:
        s1[n[0]-1] = n[1]
    print(key, s1)
    print(s)

However it seems that even if I am only modifying the list s1 which is a copy of s, I am nontheless modifying s as well, as it returns:

change 1 ['B', 'A', 'B', 'A', 'B', 'A', 'B']
['B', 'A', 'B', 'A', 'B', 'A', 'B']
change 2 ['B', 'B', 'B', 'B', 'B', 'B', 'B']
['B', 'B', 'B', 'B', 'B', 'B', 'B']

So although I get the first list right, the second isn't and I don't understand why.

Could you help me see what is wrong in my code, and how to make it work? Many thanks!

2
  • 3
    s1 isn't a copy of s, it is s. The two variables are different names for the same object. Do s1 = s.copy() if you want it to be a copy. Commented Oct 24, 2022 at 14:59
  • 1
    In python, "Assignment never copies data". You might be interested in this talk: youtu.be/_AEJHKGk9ns (Facts and Myths about Python Names and Values, Ned Batchelder) Commented Oct 24, 2022 at 15:06

2 Answers 2

1

In your code s1 isn't a copy of s, it's just another name for s.

I'd suggest doing this by just building a new list in a comprehension, e.g.:

>>> change={'change 1': [(1, 'B'), (3, 'B'), (5, 'B'), (7, 'B')], 'change 2': [(2, 'B'), (4, 'B'), (6, 'B')]}
>>> s=['A', 'A', 'A', 'A', 'A', 'A', 'A']
>>> for t in change.values():
...     d = dict(t)
...     print([d.get(i, x) for i, x in enumerate(s, 1)])
...
['B', 'A', 'B', 'A', 'B', 'A', 'B']
['A', 'B', 'A', 'B', 'A', 'B', 'A']

But if you change your original code to initialize s1 to s.copy() it seems to work:

>>> for key in change:
...     s1 = s.copy()
...     for n in change[key]:
...         s1[n[0]-1] = n[1]
...     print(s1)
...
['B', 'A', 'B', 'A', 'B', 'A', 'B']
['A', 'B', 'A', 'B', 'A', 'B', 'A']
Sign up to request clarification or add additional context in comments.

Comments

0

If you want to make sure a copy of an instance of a class with all its dependencies is completely being copied, use deepcopy as follows:

import copy 
change={'change 1': [(1, 'B'), (3, 'B'), (5, 'B'), (7, 'B')], 'change 2': [(2, 'B'), (4, 'B'), (6, 'B')]}
s=['A', 'A', 'A', 'A', 'A', 'A', 'A']
for key in change:
    s1=copy.deepcopy(s)
    for n in change[key]:
        s1[n[0]-1] = n[1]
    print(key, s1)
    print(s)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.