Reputation: 79
My 1-D array is importing correctly and is displayed correctly, my logic also works when I do it by hand so I'm not sure what is wrong. When I copy each value in the 1-D array into the 2-D it is doing an odd pattern of copying as well as putting the wrong values in.
This is the 1-D array:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
This is the following output:
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
row: 0 col: 0
0
In loop... [[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
row: 0 col: 1
1
In loop... [[2, 0, 0, 0], [2, 0, 0, 0], [2, 0, 0, 0], [2, 0, 0, 0]]
row: 0 col: 2
2
In loop... [[3, 0, 0, 0], [3, 0, 0, 0], [3, 0, 0, 0], [3, 0, 0, 0]]
row: 0 col: 3
3
In loop... [[4, 0, 0, 0], [4, 0, 0, 0], [4, 0, 0, 0], [4, 0, 0, 0]]
row: 1 col: 0
4
In loop... [[4, 5, 0, 0], [4, 5, 0, 0], [4, 5, 0, 0], [4, 5, 0, 0]]
row: 1 col: 1
5
In loop... [[4, 6, 0, 0], [4, 6, 0, 0], [4, 6, 0, 0], [4, 6, 0, 0]]
row: 1 col: 2
6
In loop... [[4, 7, 0, 0], [4, 7, 0, 0], [4, 7, 0, 0], [4, 7, 0, 0]]
row: 1 col: 3
7
In loop... [[4, 8, 0, 0], [4, 8, 0, 0], [4, 8, 0, 0], [4, 8, 0, 0]]
row: 2 col: 0
8
In loop... [[4, 8, 9, 0], [4, 8, 9, 0], [4, 8, 9, 0], [4, 8, 9, 0]]
row: 2 col: 1
9
In loop... [[4, 8, 10, 0], [4, 8, 10, 0], [4, 8, 10, 0], [4, 8, 10, 0]]
row: 2 col: 2
10
In loop... [[4, 8, 11, 0], [4, 8, 11, 0], [4, 8, 11, 0], [4, 8, 11, 0]]
row: 2 col: 3
11
In loop... [[4, 8, 12, 0], [4, 8, 12, 0], [4, 8, 12, 0], [4, 8, 12, 0]]
row: 3 col: 0
12
In loop... [[4, 8, 12, 13], [4, 8, 12, 13], [4, 8, 12, 13], [4, 8, 12, 13]]
row: 3 col: 1
13
In loop... [[4, 8, 12, 14], [4, 8, 12, 14], [4, 8, 12, 14], [4, 8, 12, 14]]
row: 3 col: 2
14
In loop... [[4, 8, 12, 15], [4, 8, 12, 15], [4, 8, 12, 15], [4, 8, 12, 15]]
row: 3 col: 3
15
In loop... [[4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16]]
Before return... [[4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16]]
Here is the function code:
def makeTwoArr(array, height, width):
print(array)
newArray=[]
line=[0]*width
for i in range(height):
newArray.append(line)
location=0
print(newArray)
for row in range(height):
for col in range(width):
print("row: ",row," col: ",col);
print(location)
## #print(array[location])
newArray[col][row]=array[location]
## print(newArray)
location+=1
print("In loop...",newArray)
print("Before return...",newArray)
return newArray
Both me and my computer science professor can't figure out why the values are wrong, or why its filling certain spots at the wrong iteration.
Upvotes: 3
Views: 50
Reputation: 29690
When you use line=[0]*width
and then append(line)
you actually create multiple references to the same line, hence when you modify one line in your loops you actually modify all lines. You need to actually create different lines such that values aren't modified everywhere by reference in the same list during assignment. It is always important to remember that lists are mutable, and appending the same one creates references to the same list.
As an aside, I'm guessing for your (educational) purposes you need to do assignment in this looping fashion, but if you were trying to do so more idiomatically with the standard library you could use iter
and zip
with unpacking to create lists of lists, although this would only work were you to be assured that your original list has the correct number of elements. This works by passing the same iterator to zip
your desired number of times in order to unpack your entire sequence.
new_arr = list(map(list,zip(*[iter(arr)]*4)))
Outputs:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
Upvotes: 3
Reputation: 3889
As Donkey Kong rightly mentioned, you were creating reference to the same line. Also, the loop construct a bit incorrect.
def makeTwoArr(array, height, width):
print(array)
newArray=[[0 for x in range(width)] for x in range(height)]
print(newArray)
row=0
col=0
# Use single loop where possible. Loop in a loop may hamper performance.
for location in range( 0, len(array)):
print("row: ",row," col: ",col);
print(location)
newArray[row][col]=array[location]
col+=1
if col == width:
row+=1
col=0
print("In loop...",newArray)
print("Before return...",newArray)
return newArray
oldarr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
newarr = makeTwoArr(oldarr, 4, 4)
print "############"
print ("New Array is", newarr)
I tried a different approach to loop the source array instead of the destination. The reason was to have single loop instead of double loops. Though both could be deemed as correct.
Please take this solution as a starting point and not a copy paste solution.
Upvotes: 2
Reputation: 253
I believe this is happening because every row in new_array
is actually pointing to the same exact list, line
.
Change your code like this and it should work:
def makeTwoArr(array, height, width):
print(array)
newArray=[]
#line=[0]*width # DON'T DO THIS
for i in range(height):
newArray.append([0]*width) # DO THIS INSTEAD
location=0
print(newArray)
for row in range(height):
for col in range(width):
print("row: ",row," col: ",col);
print(location)
newArray[col][row]=array[location]
print(newArray)
location+=1
print("In loop...",newArray)
print("Before return...",newArray)
return newArray
Upvotes: 0