64_Tesseract
64_Tesseract

Reputation: 63

Python array value allocation glitch

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!

Upvotes: 1

Views: 66

Answers (3)

David Culbreth
David Culbreth

Reputation: 2796

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.

Upvotes: 0

user8408080
user8408080

Reputation: 2468

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

Upvotes: 0

dataista
dataista

Reputation: 3457

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.

Upvotes: 1

Related Questions