Syntax Error:Creating An 2d List Filled With Zero - python

How Could I Initialize An 2D List Filled With Zeroes Without Any Additional Library/Module
here what is my attempt
table = [0 for i in range(amount + 1)[0 for j in range(len(coins))]]
it works in case of 1d list:Vector But Fails In Case Of 2d
Code:
table = [0 for i in range(amount + 1)]
O/P:
[0,0,0,0,0,0,0,0,0,0,0,0]
Code:
table = [0 for i in range(amount + 1)[0 for j in range(len(coins))]]
O/P:
Syntax Error

You are putting the inner comprehension part in the wrong position. Try:
rows, cols = 4, 5
table = [[0 for _ in range(cols)] for _ in range(rows)]
print(table)
# [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
First, _ here is nothing strange; it is just a dummy name, which we don't care. We could name it i for example, and nothing changes.
[... for _ in range(rows)] makes a list with length rows, with the items given by .... Now ... was [0 for _ in range(cols)], i.e., a list of zeros with length cols. Therefore, the result is a list (having length row) of [0, 0, ..., 0].

Related

Replace all but the first 1 in an array with 0

I am trying to find a way to replace all of the duplicate 1 with 0. As an example:
[[0,1,0,1,0],
[1,0,0,1,0],
[1,1,1,0,1]]
Should become:
[[0,1,0,0,0],
[1,0,0,0,0],
[1,0,0,0,0]]
I found a similar problem, however the solution does not seem to work numpy: setting duplicate values in a row to 0
Assume array contains only zeros and ones, you can find the max value per row using numpy.argmax and then use advanced indexing to reassign the values on the index to a zeros array.
arr = np.array([[0,1,0,1,0],
[1,0,0,1,0],
[1,1,1,0,1]])
res = np.zeros_like(arr)
idx = (np.arange(len(res)), np.argmax(arr, axis=1))
res[idx] = arr[idx]
res
array([[0, 1, 0, 0, 0],
[1, 0, 0, 0, 0],
[1, 0, 0, 0, 0]])
Try looping through each row of the grid
In each row, find all the 1s. In particular you want their indices (positions within the row). You can do this with a list comprehension and enumerate, which automatically gives an index for each element.
Then, still within that row, go through every 1 except for the first, and set it to zero.
grid = [[0, 1, 0, 1, 0], [1, 0, 0, 1, 0], [1, 1, 1, 0, 1]]
for row in grid:
ones = [i for i, element in enumerate(row) if element==1]
for i in ones[1:]:
row[i] = 0
print(grid)
Gives: [[0, 1, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]
You can use cumsum:
(arr.cumsum(axis=1).cumsum(axis=1) == 1) * 1
this will create a cummulative sum, by then checking if a value is 1 you can find the first 1s

Initialize 2D list

The follow codes didn't behave like I expected. Is this an incorrect way of initializing a 2D list filled with 0?
matrix = [[0] * 4] * 4
for row in matrix:
print(row)
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
matrix[0][0] = 1
for row in matrix:
print(row)
[1, 0, 0, 0]
[1, 0, 0, 0]
[1, 0, 0, 0]
[1, 0, 0, 0]
Use matrix = [[0 for i in range(4)] for j in range(4)] instead of matrix = [[0] * 4] * 4.
matrix = [[0 for i in range(4)] for j in range(4)]
matrix[0][0] = 1
for row in matrix:
print(row)
Output:
[1, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
I actually ran into this problem a while ago! No, this isn't the correct way, at least for what you're expecting to happen.
The problem is that when you initialise this list, you create a list of references back to the first item, so when you modify it, you modify all of them, because in reality they all point to the same object in memory.
Instead of that you can do something like this:
x = 4
y = 4
matrix = [[0]*x for _ in range(y)]
With a result of:
[[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]
Then matrix[0][0] = 1 only sets the first element of the first list to 1.
You can extend this into 3D and beyond by simply adding a new layer of for __ in range(z) on the end and and wrapping it in more square brackets.
That is because the matrix is composed of a copy of the list [0,0,0,0].
This should work:
matrix = [[0 for i in range(4)] for j in range(4)]
matrix[0][0] = 1
In the general case you can make something like numpy.full (but for lists instead of arrays):
def full(shape, fill_value=0):
if len(shape) > 1:
return [full(shape[1:], fill_value) for _ in range(shape[0])]
else:
return [fill_value] * shape[0]
matrix = full((4, 4), 0)

How to assign value to an element of 2d array with dynamic size?

I want to create an adjacency matrix for a graph without using any libraries. The problem is the size of the graph is not static and it increases over time. So I can not use a command like:
adj = [ [None for i in range(5)] for j in range(4) ]
and for example, assign 4 to element (1,1):
adj[1][1]=4
I have created an empty list called adj:
adj = []
now each time a node is added to the graph I add a list to adj:
adj.append([])
How can I assign a value to a specific element of the matrix, as I did with q[1][1]=4 when the size was fixed?
You can start with any default size and then use extend to add elements to a sublist, or add a new sublist.
adj = [ [0 for i in range(2)] for j in range(2) ]
print(adj)
#[[0, 0], [0, 0]]
adj[0].extend([1, 1])
#[[0, 0, 1, 1], [0, 0]]
print(adj)
adj.extend([[0, 0, 0, 0, 0]])
print(adj)
#[[0, 0, 1, 1], [0, 0], [0, 0, 0, 0, 0]]
Once you resize your list based on requirement, then you can assign your elements.
adj[0][0] = 2
adj[1][1] = 3
adj[2][2] = 4
print(adj)
#[[2, 0, 1, 1], [0, 3], [0, 0, 4, 0, 0]]

Fill a dummy matrix with help of dictionary keys

I want to use dictionary keys to get to their respective values and then use these values to reference certain elements in my 2D Array.
I do have a 2d-dummy matrix which I create like this:
self.matrix = [[0] * self.length] * self.length
which creates an N x N matrix depending on the length
I also have a sorted list of nodes that have names (=keys) and I want to map these names to indices (=values) 0..N
self.data = dict(zip(self.nodes, self.index_array))
It all works perfectly fine up until I try to fill my dummy adjacency matrix with "1" for Ni is connected to Nj.
"edges" is a list of tuples: edges = [("u1","v1"),("u1","v2"),...,("ui","uj")]
for row in edges:
self.matrix[self.data[row[0]]][self.data[row[1]]] = 1
Now when I run the method above, I get a matrix that is full of ones when there should only be ones for every connection between node u and node v
I tried modelling this problem in a smaller manner and here it worked perfectly! I don't know what's going on.
a = {"3": 0, "4": 1, "5": 2}
edges = [("3", "5"), ("4", "3"), ("5", "3")]
nodes = ["3", "4", "5"]
index = [0, 1, 2]
data = dict(zip(nodes, index))
matrix = [[0, 0, 0],
[0, 0, 0],
[0, 0, 0]]
for row in edges:
matrix[data[row[0]]][data[row[1]]] = 1
print(a)
print(data)
print(matrix)
This does not create the matrix correctly:
self.matrix = [[0] * self.length] * self.length
Use:
self.matrix = [[0] * self.length for _ in range(self.length)]
The reason is multiplying a list creates multiples of the references in the list, so every row is a reference to the same list in your original code.
Here's an example of the difference:
>>> A = [[0] * 3] * 3
>>> A
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> A [0][0] = 1
>>> A
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
Note above how all three rows changed. This is due to each row containing a copy of the same list:
>>> A = [[0] * 3 for _ in range(3)]
>>> A
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> A[0][0] = 1
>>> A
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]
Now a new row of three zeroes is created for each row. Changing one element in a row doesn't change all the rows.
Note that [0] * 3 also duplicates the references to the integer zero as well. Being an immutable object this isn't a problem, but if you have a mutable object you don't want three copies. You would use [mutable_obj() for _ in range(3)] to create 3 different objects, so if you edit one the others don't change.
By using the * operator on a list of sublists you're repeating the same references to the sublists, so any change made to a sublist will be reflected on all other items holding the same reference to the sublist.
You can initialize self.matrix with a list comprehension instead:
self.matrix = [[0] * self.length] for _ in range(self.length)]

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!

Categories