In relation to the question:
How to initialize a two-dimensional array in Python?
While working with a two dimentional array, I found that initializing it in a certain way would produce unexpected results. I would like to understand the difference between initializing an 8x8 grid in these two ways:
>>> a = [[1]*8]*8
>>> a
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
vs.
>>> A = [[1 for i in range(8)] for j in range(8)]
>>> A
[[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1], \
[1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1]]
The unexpected results were that any element accessed with the indeces [0-6][x] would point to the last row in [7][x]. The arrays look identical in the interpreter, hence my confusion. What is wrong with the first approach?
If relevant, these arrays hold references to GTK EventBoxes that represent the squares of a chess board. After changing the initialization approach to the list-comprehension method, the squares respond properly to the intended hover and click events.
List comprehensions on tiny lists are faster than doing the same with numpy as the performance gain from using numpy is not enough to offset the overhead of creating an array. Using max(0.0, min(num, 1.0)) over np.
Lists and strings have a lot in common. They are both sequences and, like pythons, they get longer as you feed them. Like a string, we can concatenate and multiply a Python list.
If you multiply a python list by a number, it gets repeated N times. Copied! Multiplying a Python list by N, returns a new list containing the elements of the original list repeated N times.
When you create the 2D array using a = [[1]*8]*8
then the * operator creates 8 references to the same object. Therefore, [1]*8
means create an array of size 8 where all 8 elements are the same object (same reference). Since all elements are the same references updating the value to which that reference points will change the value of every element in the array.
Using the list comprehension A = [[1 for i in range(8)] for j in range(8)]
ensures that each element in your 2D array is uniquely referenced. This avoids the erroneous behavior you were seeing where all of the elements were updating simultaneously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With