1
megaList = []
clmsArrow = [[3],[2,3,4],[1,3,5],[3],[3],[3],[3]]

def columnState(y,amnt):
    "-1 for all values in a list of lists"
    megaList.append(y)
    print(y)
    for i in range(len(y)):
        for j in range(len(y[i])):
            y[i][j] -= 1
            if y[i][j] == 0:
                y[i][j] = 5

    if amnt != 1:
        return columnState(y,amnt-1)

columnState(clmsArrow,5)
print('\n')
for x in megaList:
    print(x)

''Output''

[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[2], [1, 2, 3], [5, 2, 4], [2], [2], [2], [2]]
[[1], [5, 1, 2], [4, 1, 3], [1], [1], [1], [1]]
[[5], [4, 5, 1], [3, 5, 2], [5], [5], [5], [5]]
[[4], [3, 4, 5], [2, 4, 1], [4], [4], [4], [4]]


[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]

Why can't I write out to global variable (list) properly? All I get is the same first function input times five

As seen in the output inside function everything is alright, but when I try to add the same variable to a list outside the function something goes wrong

7
  • 1
    Inside function you need to write: global megaList (which you also need to define, before you go into function, as an empty list I suppose) Commented Oct 15, 2019 at 15:35
  • Another solution would be to wrap this function in a class and make megaList a class attribute. This means you don't have to use a global, and all methods in the class can access it. Commented Oct 15, 2019 at 15:48
  • 3
    @GrzegorzSkibinski, there's no need to mark a name as global if it's never rebound inside the function (if there's no assignment like megaList = 'whatever') Commented Oct 15, 2019 at 15:48
  • "Why can't I write out to global variable (list) properly?" What makes you think you can't do this? Can you show some example output and explain what you want it to be instead. Commented Oct 15, 2019 at 15:49
  • Also read this article to get some tips about debugging your code. Commented Oct 15, 2019 at 15:50

1 Answer 1

1

This is because you keep adding references to y in your mega_list. And if you change y you also change all the references to y. For example:

a = [1, 2]
b = [a, a]
print(b)
a[0] = 99
print(b)

which prints

[[1, 2], [1, 2]]
[[99, 2], [99, 2]]

notice how b changed even though I only change a. This is because b contains references to a instead of copies.

To fix this in your code you can simply add this to start of your function

y = deepcopy(y)

you'll need to also add

from copy import deepcopy

the reason you need deepcopy instead of simply doing y[:] is because your y is ` nested list i.e. all the lists inside of it are also just references to other lists and those also need to be copied.

Finally, the reason you are getting back to your original value is because you made amnt equal 5 and your function does nothing if you run if 5 times because of

        if y[i][j] == 0:
            y[i][j] = 5

so they are changing, they're just landing up back where they started. If you run

columnState(clmsArrow, 4)

for example then you'll see the change i.e. you get

[[3], [2, 3, 4], [1, 3, 5], [3], [3], [3], [3]]
[[2], [1, 2, 3], [5, 2, 4], [2], [2], [2], [2]]
[[1], [5, 1, 2], [4, 1, 3], [1], [1], [1], [1]]
[[5], [4, 5, 1], [3, 5, 2], [5], [5], [5], [5]]

[[4], [3, 4, 5], [2, 4, 1], [4], [4], [4], [4]]
[[4], [3, 4, 5], [2, 4, 1], [4], [4], [4], [4]]
[[4], [3, 4, 5], [2, 4, 1], [4], [4], [4], [4]]
[[4], [3, 4, 5], [2, 4, 1], [4], [4], [4], [4]]
Sign up to request clarification or add additional context in comments.

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.