Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Element (array) "multiplication" vs. list comprehension initialization [duplicate]

Tags:

python

arrays

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.

like image 372
Ярослав Рахматуллин Avatar asked Sep 21 '13 13:09

Ярослав Рахматуллин


People also ask

Is list comprehension faster than NP array?

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.

Can you multiply a Python list?

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.

What happens when you multiply a list in Python?

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.


1 Answers

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.

like image 50
bpmason1 Avatar answered Sep 25 '22 09:09

bpmason1