Multiply arrays to make matrix gives unexpected result [duplicate] - python

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 8 years ago.
Suppose I have this code:
dim = 3
eye = [[0] * dim] * dim
and it is a list of list, I checked
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
Now, if I do this, I get:
eye[1][2] = 1
eye
[[0, 0, 1], [0, 0, 1], [0, 0, 1]]
However, if I manually put in this expression, the above code works as expected:
eye2=[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
eye2[1][2] = 1
eye2
[[0, 0, 0], [0, 0, 1], [0, 0, 0]]
What is the difference between the two ?
Update: Thanks for all the explanations, suppose I have this code:
a = [0]
type(a)
b = a * 3 # or b = [[0] *3]
So, b holds the 3 references to a. And I expect changing b[0] or b[1] or b[2] will change all 3 elements.
But this code shows the normal behavior, why is that ?
b[1] = 3
b
[0, 3, 0]

Any array entry is as a label of memory address and when you multiple it with a variable actually you create a pointer to 3 palace in your array ! you can figure it out with a list comprehension as below :
Matrix = [[0 for x in xrange(3)] for x in xrange(3)]

dim = 3
eye = [[0] * dim] * dim
its make the copy of same, of if you change at one place it will be reflected to all

dim = 3
eye = [[0] * dim] * dim
print id(eye[0])
print id(eye[1])
print id(eye[2])
Ouput:-
139834251065392
139834251065392
139834251065392
So when you are doing eye = [[0] * dim] * dim it actually refrencing
refrencing three list to same object that is eye.
while in other case
eye2=[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
print id(eye2[1])
print id(eye2[2])
print id(eye2[0])
ouput:-
139863345170480
139863260058256
139863260067240
Here everytime refrence id is diffrent.

Related

Updating 2D Array Values in Python - Updating whole column wrong?

I am trying to create a 2D array as such and just update single values at a time, shown here:
M = [[0]*3]*3
M[0][0] = 3
print(M)
which is returning the following:
[[3, 0 , 0], [3, 0, 0], [3, 0, 0]]
Anyone have an idea of what I've done wrong?
What your first line is doing is creating one inner length 3 list, and adding three references of it to your outer list M. You must declare each internal list independently if you want them to be independent lists.
The following is different in that it creates 3 separate instances of inner length 3 lists:
M = [[0]*3 for _ in range(3)]
M[0][0] = 3
print(M)
OUTPUT
[[3, 0, 0], [0, 0, 0], [0, 0, 0]]
The 2D array is at the same address as the first array.
M = [[0,0,0],[0,0,0],[0,0,0]]
M[0][0] = 3
print(M)
Which is returning the following:
[[3, 0, 0], [0, 0, 0], [0, 0, 0]]
FYI: Problem same as this: Why in a 2D array a and *a point to same address?

Assigning values to same lists, but get different results [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 4 years ago.
I create two same zero lists. Yet the results are different when the lists are assigned to same values. Here are my code and result.
code:
m1 = [[0] * 4] * 4
m2 = [[0 for j in range(4)] for i in range(4)]
m1[0][1] = 1
m2[0][1] = 1
print('m1:', m1)
print('m2:', m2)
result:
m1: [[0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0], [0, 1, 0, 0]]
m2: [[0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Or maybe the two lists are not the "same"? Any help would be appreciated.
In m1, you're referencing the same [[0] * 4] 4 times. Basically you're doing:
x = [0, 0, 0, 0]
m1 = [x, x, x, x]
x[1] = 1
resulting in x being [0 1 0 0]
and being repeated 4 times in m1

python two dimensional array with rows and columns

Create a two-dimensional array named A with ROWS rows and COLS columns. ROWS and COLSS are specified by the user at run time. Fill A with randomly-chosen integers from the range [ -10,99 ], then repeatedly perform the following steps until end-of-file(1) input an integer x(2) search for x in A(3) when x is found in A, output the coordinate (row,col) where x is found, otherwise output the message "x not found!"
I need help I am wondering how can we define two-dimensional array named A with ROWS rows and COLS columns. ROWS and COLSS are specified by the user at runtime in python latest version
#--------------------------------------
#Hw 7
#E80
#---------------------------------------
A = [[Rows],[ColSS]] #I really dont know how to defend this part
for i in range (-10,99): #dont worry about this its just the logic not the actual code
x = int(input("Enter a number : "))
if x is found in A
coordinate row and clumn
otherwise output "x is not found"
The idiomatic way to create a 2D array in Python is:
rows,cols = 5,10
A = [[0]*cols for _ in range(rows)]
Explanation:
>>> A = [0] * 5 # Multiplication on a list creates a new list with duplicated entries.
>>> A
[0, 0, 0, 0, 0]
>>> A = [[0] * 5 for _ in range(2)] # Create multiple lists, in a list, using a comprehension.
>>> A
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> A[0][0] = 1
>>> A
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Note you do not want to create duplicate lists of lists. It duplicates the list references so you have multiple references to the same list:
>>> A = [[0] * 5] * 2
>>> A
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> A[0][0] = 1
>>> A
[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0]] # both rows changed!

Python - Create constant array of unique elements [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 5 years ago.
I recently tried to instantiate a 4x4 constant (0's) array by using
a = [[0] * 4] * 4
which instantiates the array a as
[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
However, this does not create an array of unique elements as altering an element in any of the arrays changes all of them, e.g.:
a[0][0] = 1
alters a to
[[1, 0, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 0]]
I think I understand why this happens (copies of lists copy the list's pointer and do not create separate copies unless specified, unlike int's, etc.) but am left wondering:
Is there any quick and easy way to instantiate a constant array (without using any external modules, such as NumPy) with unique elements that can later be altered by simple a[i][j] = x addressing?
a = [[0 for _ in xrange(4)] for _ in xrange(4)]
should do it, it'll create separate lists
Just for free. What is going on here ? When one does
>>> a = [[0] * 4] * 4
first, one creates one list [0] * 4 with four 0 elements. Let call this list li.
Then when you do [li] * 4, one actually creates a list which refers four times to the same object. See
>>> [id(el) for el in a]
[8696976, 8696976, 8696976, 8696976] # in my case
Whence the (not that) curious result one gets when entry-wise assigning like so
>>> a[0][0] = 1
[[1, 0, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 0],
[1, 0, 0, 0]]
A solution is simply to ensure that each element of the list really is unique. For example doing
#Python2
>>> a = map(lambda _: [0]*4, range(4))
#Python3
>>> a = list(map(lambda _: [0]*4, range(4)))
#Python2&3
>>> a[0][0] = 1
[[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]

Constructing a two-dimensional list [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Unexpected feature in a Python list of lists
I tried to create a list in python using following statement
S = [0] * 10
And it worked out well
S[0] = 1
S
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
But when I try to generate a two-dimensional list, something unexpected occurs
S = [[0] * 10] * 2
S[0][1] = 1
S[0][2] = 2
S
[[0, 1, 2, 0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 0, 0, 0, 0, 0, 0, 0]]
Note that S[0] == S[1]
Why?
By the way, is this the best approach of constructing an 2d array? If not, what makes the best?
Because you told it to make 2 copies of the same mutable list.
S = [[0] * 10 for x in range(2)]
S = [[0] * 10] * 2 means 2 references for [[0]*10], so when your change one the other will change.By the way ,the reason why [0]*10 is fine is : a reference to a number.

Categories