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
    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? – code_dredd Nov 23 '18 at 01:08

3 Answers3

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.

dataista
  • 3,187
  • 1
  • 16
  • 23
  • 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. – AetherUnbound Nov 23 '18 at 01:49
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

user8408080
  • 2,428
  • 1
  • 10
  • 19
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.

David Culbreth
  • 2,610
  • 16
  • 26