1

Solved, thanks to everyone for their help! My array generation code was referencing the same array, so edits would apply to whole columns instead of specific points.

I'm making a few functions I can use in future programs in Python to do with arrays, such as defining them and displaying them. However, I came across a strange bug or glitch while trying to set values in order in an array from left to right. For some reason, when the program sets values on the last y value, (or actually on any value,) it sets that value for the whole column instead for just one, even though I only have 2 loops. Here's my code:

def gen(xLen, yLen, fill = 0):
    mainArr = list()
    secArr = list()
    for i in range(xLen):
        secArr.append(fill)
    for i in range(yLen):
        mainArr.append(secArr)
    return mainArr

def sums(xLen, yLen):
    newArr = gen(xLen, yLen)
    a = 0
    for y in range(yLen):
        for x in range(xLen):
            newArr[y][x] = a
            print(str(x) + ", " + str(y) + " = " + str(a)) #For debugging, what the array SHOULD contain
            a += 1
    return newArr

(Just run this with print(sums(5, 5)))

Instead of returning with [[0, 1, 2, 3, 4], ... [20, 21, 22, 23, 24]], it returns with a list full of [20, 21, 22, 23, 24] and I really don't know why.

I don't want to append a new list to another list with values already in them, for example arr.append([0, 1, 2, 3, 4]), because the array is already generated. Why doesn't this work??? It's been bugging me for weeks!

1
  • 1
    It's not clear to me what function you expect to return a list of lists, or if that's even what you're trying to get. Could you edit your question to focus more on clearly explaining your problem and what you're trying to achieve? Commented Nov 23, 2018 at 1:08

3 Answers 3

1

secArr is a reference to a list. So in gen you are actually placing n times the same reference to secArr in mainArr.

Add a print(newArr) in the for to verify this.

You can run newArr[0][1] = 1 to see how all the inner lists are affected.

You can solve this by creating a copy of secArr before appending it to mainArr in gen, like this:

mainArr.append(secArr[:])

More on the topic here or here.

Sign up to request clarification or add additional context in comments.

1 Comment

This answer is good, but I would actually suggest doing mainArr.append(secArr.copy()) - I feel that the explicit copy makes it more obvious what's going on.
0

While Julian Peller's answer answers your specific question, I would propose a way cleaner and more pythonic way to do your tasks:

def gen2(xLen, yLen, fill=0):
    return [[fill for x in range(xLen)] for y in range(yLen)]

def sums2(xLen, yLen):
    return [[y*yLen+x for x in range(xLen)] for y in range(yLen)]

These functions are using list comprehensions which are more readable and avoid making errors like yours for example

Comments

0

You are seeing the same effects as the person who asked this question. I hope my answer, and the other linked answers can help you understand why this is happening, and how to fix it.

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.