Precautions When Initializing Elements of a 2D Array with the Same Value
This post is one of reflection ㅠㅠ
I want to correct the mistakes I made while taking the coding test!
Problem Definition
The issue here is about initializing and modifying array elements.
I initialized a 2D array with the same elements in Python like this.
two_arr = [[False] * 2] * 5
When you look at the output:
[
[False, False],
[False, False],
[False, False],
[False, False],
[False, False]
]
You can see the output consists of a False
list in a 2*5 shape.
It looks like it’s initialized as I intended!
But let’s try changing a particular element in the array.
two_arr[0][0] = True
I expected the element False
in the first array to change to True
, like this:
[
[True, False],
[False, False],
[False, False],
[False, False],
[False, False]
]
However, when you actually print it, you see this result:
[
[True, False],
[True, False],
[True, False],
[True, False],
[True, False]
]
I changed only [0][0]
, but it affected the 0th element of every element. What’s going on?
Solution
The problem lies in the multiplication operation (*
) while declaring a Python array with the same elements.
When copying a specific element using the multiplication operation in a 1D array, like [False] * 2
, it works correctly because it copies the value False
twice to place in the list.
The reason is that the target to copy is not a list
but a value False
. As a result, a list like [False, False]
is formed.
However, the issue arises in the second step. When copying the array declared as [[False] * 2] * 5
, similar to the code below, a problem occurs.
The list instance such as [[False] * 2]
is an address
, not a value
.
Do you understand? Ultimately, it’s the same as giving the command to copy the address of [False, False]
five times.
In simpler terms, it copied the address containing [False, False]
five times. Therefore, because each column’s address shares the elements, changing a part of one row makes it act as if a part of the entire row is changed.
To initialize arrays as intended, you need to manually initialize them using a for
loop. Since [False, False]
is called at different times as the loop iterates, different addresses are assigned.
To solve this, you can use the append()
function like this:
two_arr = []
for _ in range(5):
two_arr.append([False] * 2)
If you want your code to look cleaner, you can use list comprehensions to write it more neatly:
two_arr= [[False] * 2 for _ in range(5)]
Comparing the output afterwards, you’ll see it comes out as intended.
Output
[
[True, False],
[False, False],
[False, False],
[False, False],
[False, False]
]
In Conclusion
- Through this coding test, I’ve realized the importance of cross-checking even what I already know. I implemented all the important logic, but I didn’t expect errors in such a place.. :(
- List variables are objects, so they have address values unlike
primitive type
variables. If you’re reading this post, remember this to avoid making the same mistakes I did!