Jrakru56
Jrakru56

Reputation: 1321

Variable scope is incorrectly global

My original variable seems to be global since it is changed after passing a function, updateSudoku. From my understanding, the variable scope inside a function should be local to that function only. Could someone explain why code is failing?

For example, the value in the lower left corner has correctly been changed but a test on my variable show that they are equal. Somehow, along the way, I changed the variable original without referring to it.

From the python documentation, I found the following but I am not sure how it helps me out. In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

Code:

def print_sudoku(board):
    print("-"*37)
    for i, row in enumerate(board):
        print(("|" + " {}   {}   {} |"*3).format(*[x if x != 0 else " " for x in row]))
        if i == 8:
            print("-"*37)
        elif i % 3 == 2:
            print("|" + "---+"*8 + "---|")
        else:
            print("|" + "   +"*8 + "   |")

original = [[0, 0, 1, 0, 3, 0, 0, 0, 0], [0, 3, 0, 0, 0, 6, 1, 7, 0], [0, 0, 0, 0, 0, 0, 0, 3, 0], [0, 6, 7, 3, 1, 0, 8, 0, 9], [8, 1, 3, 4, 0, 0, 5, 0, 7], [0, 2, 0, 0, 8, 7, 0, 1, 3], [3, 0, 0, 0, 0, 0, 7, 0, 0], [7, 0, 0, 0, 0, 0, 3, 5, 0], [0, 0, 6, 0, 0, 3, 0, 0, 0]]

updates = [[], [], [(1, [(8, 0)])], [(1, [(2, 5)])], [], [], [], [], []]

print_sudoku(original)

def updateSudoku(sudoku, updates):

    newVar=sudoku

    for b in updates:
        for soln in b:
            newVar[soln[1][0][0]][soln[1][0][1]]=soln[0] 


    return newVar

newSudoku=updateSudoku(original, updates)

print_sudoku(newSudoku)
print(original==newSudoku)

Output:

-------------------------------------
|         1 |     3     |           |
|   +   +   +   +   +   +   +   +   |
|     3     |         6 | 1   7     |
|   +   +   +   +   +   +   +   +   |
|           |           |     3     |
|---+---+---+---+---+---+---+---+---|
|     6   7 | 3   1     | 8       9 |
|   +   +   +   +   +   +   +   +   |
| 8   1   3 | 4         | 5       7 |
|   +   +   +   +   +   +   +   +   |
|     2     |     8   7 |     1   3 |
|---+---+---+---+---+---+---+---+---|
| 3         |           | 7         |
|   +   +   +   +   +   +   +   +   |
| 7         |           | 3   5     |
|   +   +   +   +   +   +   +   +   |
|         6 |         3 |           |
-------------------------------------
-------------------------------------
|         1 |     3     |           |
|   +   +   +   +   +   +   +   +   |
|     3     |         6 | 1   7     |
|   +   +   +   +   +   +   +   +   |
|           |         1 |     3     |
|---+---+---+---+---+---+---+---+---|
|     6   7 | 3   1     | 8       9 |
|   +   +   +   +   +   +   +   +   |
| 8   1   3 | 4         | 5       7 |
|   +   +   +   +   +   +   +   +   |
|     2     |     8   7 |     1   3 |
|---+---+---+---+---+---+---+---+---|
| 3         |           | 7         |
|   +   +   +   +   +   +   +   +   |
| 7         |           | 3   5     |
|   +   +   +   +   +   +   +   +   |
| 1       6 |         3 |           |
-------------------------------------
True

Upvotes: 0

Views: 1180

Answers (1)

jarmod
jarmod

Reputation: 78918

Global scope is irrelevant in this case.

What is going on here is that you have passed original, which is a list, as a parameter to the updateSudoku() function. Lists are mutable objects, therefore any modification you make to the list within that function will modify the list in place. It will change the original list's contents.

If you want to avoid this, you should deep copy the list within the function.

I recommend:

Upvotes: 1

Related Questions