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] * 5When 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] = TrueI 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 typevariables. If you’re reading this post, remember this to avoid making the same mistakes I did!