Reputation: 63
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
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
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
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