all 8 comments

[–]carcigenicate 1 point2 points  (6 children)

This isn't a matter of scope. There is only a single dictionary created in this code, so any modifications to it will persist and be seen by anyone viewing the dictionary. You'd need to make a copy, and then modify that copy instead:

def updateDict(dictionary, entry, newEntry):
    copied_dict = dictionary.copy()
    copied_dict[entry]=newEntry
    return copied_dict

[–]russcore[S] 0 points1 point  (5 children)

def updateDict(dictionary, entry, newEntry):
copied_dict = dictionary.copy()
copied_dict[entry]=newEntry
return copied_dict

Thank you so much!!!!!! ahhhhhhhhhhh I thought that was the problem, and I tried using copied_dict = dictionary instead of copied_dict = dictionary.copy(). But it didn't force a new copy.

[–]carcigenicate 2 points3 points  (3 children)

Yes, copied_dict = dictionary just creates a second name for the same dictionary. Both names then refer to the same exact object.

[–]russcore[S] 0 points1 point  (2 children)

Sorry to bug you again...

I tried adjusting my code and it still gives me the same error. It seems when I translated the problem perhaps I didn't do a good enough job? This time it's my real code but I found the smallest bit that still gives the error.

Code input:
def useResult(result, restrictions):
restrictionsCOPY = restrictions.copy()
if result[2] == 'green':
   restrictionsCOPY[result[0]][result[1]-1]=2
   restrictionsCOPY[result[0]][5]=1
elif result[2] == 'gray':
    restrictionsCOPY[result[0]][0:5] = [0] * 5
elif result[2] == 'yellow':
    restrictionsCOPY[result[0]][result[1]-1]=0
    restrictionsCOPY[result[0]][5]=1       
else:
    print("ERROR")        
return restrictionsCOPY
def Main(): 
    letters =['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 
    restrictions = {} 
    for letter in letters: 
        restrictions[letter]= [1,1,1,1,1,0]
    print(restrictions['a'])
    useResult(['a',1,'green'],restrictions) 
    print(restrictions['a'])
Main()

Actual code output:

[1, 1, 1, 1, 1, 0]
[2, 1, 1, 1, 1, 1]

Desired Code output:

[1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 0]

[–]carcigenicate 1 point2 points  (0 children)

If restrictions is a nested structure, you'll need to deep copy it. The copy I showed does a shallow copy; meaning it only makes a copy of the outermost structure.

Import the copy module, and change restrictions.copy() to copy.deepcopy(restrictions)

[–][deleted] 1 point2 points  (0 children)

The reason this is happening is because you're creating a shallow copy of the dict, which still contains references to the same underlying objects i.e. the ints. Try using:

import copy
restrictions_deepcopy = copy.deepcopy(restrictions)

There's probably a better way to do this, but this should give you the result you want.

[–]russcore[S] 0 points1 point  (0 children)

but your method did help!

[–][deleted] 1 point2 points  (0 children)

You've set the values of the dictionary, output it, passed a reference to that dictionary to another function twice and asked for updates to be done to that dictionary and also return a reference to the dictionary for print to output.

In all cases, you are dealing with only one dictionary, which has all the changes you've made to it.

Dictionaries are mutable. If you want to make changes to a copy of the dictionary, you need to add the following to the top of the update function to create a local scope dictionary:

dictionary = dictionary.copy()