Update value in Multidimensional list in Python [duplicate] - python

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 5 years ago.
I have an list like the following
line_37_data = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
When I print line_37_data[0][0] , the value 0 is printed.
When I update the list as line_37_data[0][0] = 5, the list gets modified like below
[[5, 0, 0], [5, 0, 0], [5, 0, 0]]
How can I can update the value in the list based on the index ?
Note :- I don't use NumPy. This is pure plain Python without any libraries. I am using 2.7 and not Python 3

If you pass in the same list as each element of your outer list, manipulating it will show in each place it appears. If you're just looking to fill a 2d list with zeros, list comprehension would be easy:
def generate_2d(h, w):
return [[0 for x in range(w)] for y in range(h)]
array = generate_2d(3, 3)
# Format is array[y][x] based on names in function
array[0][0] = 5
array[1][2] = 7
assert array == [
[5, 0, 0],
[0, 0, 7],
[0, 0, 0]]

Related

Why is this happening when I'm trying to change an index from a list? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 2 months ago.
Input = 5
GM1 = [0 for x in range(Input)]
GameBoard = [GM1 for x in range(Input)]
print(*GameBoard, sep="\n")
GameBoard[1][1] = 5
print(*GameBoard, sep="\n")
ok so in the final print statement, I expect this result:
[0, 0, 0, 0, 0]
[0, 5, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
[0, 0, 0, 0, 0]
but instead, I'm getting
[0, 5, 0, 0, 0]
[0, 5, 0, 0, 0]
[0, 5, 0, 0, 0]
[0, 5, 0, 0, 0]
[0, 5, 0, 0, 0]
Why is this happening and how can I solve this?
I think the problem is about list comprehension I used.
Try this:
GameBoard = [GM1.copy() for x in range(Input)]
And this article will help you to understand what's going on:
Immutable vs Mutable types
and how can I solve this?
it's quite easy:
GameBoard = [[0]*Input for _ in range(Input)]
The problem is not the list comprehension, but something that is called aliasing. In your case, this means that GameBoard is actually referencing the same object 'GM1' five times.
When you modify one item in a row of GameBoard, you are actually modifying the item at index 1 of the GM1 list, which is shared by all of the rows of GameBoard. Since GM1 is used as the rows of GameBoard, this means that the change is applied to all of the rows of GameBoard.
This issue can be avoided by making a copy of GM1, instead of a direct reference, as iYasha pointed out in their answer:
GameBoard = [GM1.copy() for x in range(Input)]
Each row will then be a separate list, so modifying one item in the list will not affect the other rows (lists).

Assigning value in python 2d list [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 12 months ago.
I have previously worked in C, I am facing problem in assigning value in 2d list
graph = [[0]*3]*3
print(graph)
graph[0][1] = 3
print(graph)
Output
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[0, 3, 0], [0, 3, 0], [0, 3, 0]]
Expected output :
[[0, 3, 0], [0, 0, 0], [0, 0, 0]]
Is there any way to assign values other than using numpy array as answered in
Assigning values Python 2D Array
you can use a for loop to do this simply
a = []
for i in range(3):
a.append([0]*3)

summing list inside list by position in python [duplicate]

This question already has answers here:
Sum of list of lists; returns sum list
(10 answers)
Closed 5 years ago.
I have a list that looks like this and I would like to sum up the values at each position so as produce a list with only three values
print x
[[0, 0, -1], [0, 0, -1], [0, 0, 0], [1, 0, 0], [0, 0, 1]]
For example, x[0][1] should be summed with the value in x[1][1], x[2][1], x[3][1], x[4][1]. Likewise x[0][2] should be summed with x[1][2], x[2][2], etc.
the output should look like this
print output
[1, 0, -1]
Using numpy:
np.sum(x, axis=0)
Using native list:
[sum(y) for y in zip(*x)]
I would use Julien's answer as it is more readable but to give you an alternative, you can use map and zip functions.
list(map(sum, zip(*x)))
Just combine for loops:
outlist=[]
for i in range(len(L[0])):
sum = 0
for subL in L:
sum += subL[i]
outlist.append(sum)
print(outlist)
Output:
[1, 0, -1]

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]]

python 2d array indexing: setting a value changing whole column? [duplicate]

This question already has answers here:
List of lists changes reflected across sublists unexpectedly
(17 answers)
Closed 7 years ago.
It might be a very stupid question but I just don't understand this code:
>>> a=[[0]*3]*3
>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][1]=3
>>> a
[[0, 3, 0], [0, 3, 0], [0, 3, 0]]
Why a call a[0][1] will initialize the whole second column to be 3?
This is because a[0][1] actually is the reference to the same lists. When you use * operator to duplicate elements into a list, these duplicate elements are not individually stored in the memory. They point to the same list, so if you modify one list, all the lists would be modified.

Categories