how to fill matrix using range without numpy? - python

I created a matrix of zeros using lists, and I want to fill it based on matrix size, but I want the numbers to come sequentially.
I tried the following
matrix = []
for i in range(3):
a =[]
for j in range(3):
a.append(i+j)
matrix.append(a)
I get this:
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
but the expected is:
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
thanks

Have your outer range loop with a step to provide the base value for each level. In this case, just change:
for i in range(3):
to:
for i in range(0, 9, 3):
It might be slightly more readable to phrase it in terms of a named variable like dim (for "dimension"):
dim = 3
for i in range(0, dim ** 2, dim):
a = []
for j in range(dim):
a.append(i+j)
matrix.append(a)

Tagging on to #ShadowRanger's answer, rather than appending you can use a list comprehension if you would like.
dim = 3
matrix = [list(range(i, i+dim)) for i in range(0, dim**2, dim)]

You could multiply i by 3 like so:
matrix = []
for i in range(3):
a =[]
for j in range(3):
a.append(3*i + j) <-----
matrix.append(a)

Related

3x3 Matrix not printing in correct format

I am trying to create a matrix that is 3x3 but it keeps returning as one line. This is the code I have tried so far.
def createSymmetricMat(n):
m = []
for i in range(n):
r = []
for j in range(n):
r.append(3*i+j)
print()
m.append(r)
return m
print(createSymmetricMat(3))
This returns
[[0, 1, 2], [3, 4, 5], [6, 7, 8]]
Any suggestions?
I see no problem with this representation of a 3x3 matrix. If you want it visually correct after you created your matrix, you can do:
for r in createSymmetricMat(3):
print(r)
which gives you:
[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
def createSymmetricMat(n):
m = []
for i in range(n):
r = []
for j in range(n):
r.append(3*i+j)
m.append(r)
# print m when updated
print(m)
return m
createSymmetricMat(3)
If you want to print each time m is updated, just add a print(m) whenever m is updated. Then you can print the entire matrix as:
for row in createSymmetricMat(3):
print(row)

python populating array using while loop

All I am trying to do is populate an array with numbers in order. So, array[0][0] = 0, array[0][1]=1, etc. Why is this not working? I cannot figure it out.
def populateArray(ar):
count = 0
i=0
j=0
while (i<len(ar)):
while (j<len(ar[i])):
ar[i][j] = count
count = count + 1
j=j+1
j=0
i=i+1
return ar
numColumns = input('how many columns?')
numRows = input('how many rows?')
arr = [[0]*int(numColumns)]*int(numRows)
arr=populateArray(arr)
print(arr)
when you initiate your arr variable, you are multiplying a list of lists with a number, this results in a "mess" because what you actually do it is to multiply only the reference of the first list (from your list of lists), so actually you have in your arr only one list and a bunch of reference to that list, to fix this you can do:
arr = [[0] * int(numColumns) for _ in range(int(numRows))]
or:
arr = [[0 for _ in range(int(numColumns))] for _ in range(int(numRows))]
after changing this in your code, for numRows = 3 and numColumns = 4 you get:
[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]
When you use this syntax to create multi dimensional array
arr = [[0]*int(numColumns)]*int(numRows)
the reference of same element is created many times , so if you assign a value to one of them then you are basically changing all the elements because they all reference to the same data.
for ex :
arr = [[0]*int(numColumns)]*int(numRows)
arr[0][1]=2
print(arr)
output
[[0, 2], [0, 2], [0, 2], [0, 2]]
I only changed one element and this is the result .
you should use :
arr = [[0 for i in range(int(numColumns))] for j in range(int(numRows))]
arr[0][1]=2
print(arr)
output :
[[0, 2], [0, 0], [0, 0], [0, 0]]
You can do this:
numColumns = input('how many columns?')
numRows = input('how many rows?')
arr = [[i+j for i in range(int(numRows))] for j in range(int(numColumns))]
arr=populateArray(arr)
print(arr)
The problem with your code is that you append same array to the main array multiple times, like this [l, l, l] and l is a list.
So when ever you change an elemenet of l it will change all of ls in your list.
So, your code works fine but each time you change another list, all of previous list will be effected.
You can also make use of numpy for creating the structure, followed by using numpy.tolist() for converting it to a python list
import numpy as np
numColumns = int(input('how many columns?'))
numRows = int(input('how many rows?') )
arr = np.arange(numRows*numColumns).reshape(numRows, numColumns).tolist()
print(arr)

Many for in one line in python generator

I can't understand code with multi "for"s in one generator like this, I searched Google and didn't find any answer:
print [j for i in [[1,2],[4,6]] for j in i ]
# will print [1, 2, 4, 6]
print [j for j in i for i in [[1,2],[4,6]] ]
# will print [4, 4, 6, 6]
What is the difference?
How to interpret code like this?
Hopefully the expansions will help you reason with the code. It's a lot more readable this way, in my opinion. I'm printing one element at a time instead of the whole list.
print [j for i in [[1, 2], [4, 6]] for j in i]
is equivalent to
for i in [[1, 2], [4, 6]]:
for j in i:
print j
As a result i = [4, 6].
Now,
print [j for j in i for i in [[1,2],[4,6]]]
is equivalent to
for j in i: # Remember, i = [4, 6]
for i in [[1, 2], [4, 6]]:
print j
The second generater is error, but in your code scripts, the second generator, the i will be [4, 6] after your run the first generator, so the second will output [4, 4, 6, 6]
first list comprehension is read as
mat = [[1,2],[4,6]]
a = []
for i in mat:
for j in i:
a.append(j)
print(a)
second list comprehension is read as
b = []
for j in i:
for i in mat:
b.append(j)
print(b)
Comprehensions can be interpreted as a shorthand for loops whose only statement is to append an element to the list they create. The syntax you show is how nested loops are implemented.
For example, your first snippet [j for i in [[1,2],[4,6]] for j in i] can be rewritten as
result = []
for i in [[1,2],[4,6]]:
for j in i:
result.append(j)
Note that the order of the loops in the comprehension is the same as in the expanded form.
Your second snippet [j for j in i for i in [[1,2],[4,6]] then becomes
result = []
for j in i:
for i in [[1,2],[4,6]]:
result.append(j)
As you can see, this will simply fail with a NameError at the start of the first loop since i is not defined at that point.

Sum of two matrices

I ran into an exercise, which I have a problem with:
Write a function with two input parameters: M1 and M2, those are arrays: list of list of numbers. Return the sum of the matrices if they are compatible, or an empty list otherwise.
For example:
A = [[1, 2, 3], [4, 5, 6]]
B = [[1, 1, 1], [1, 1, 1]]
matrix_sum(A, B)
You get:
[[2, 3, 4], [5, 6, 7]]
So I tried:
def matrix_sum(M1, M2):
while len(M1)==len(M2):
res = []
for i in range(len(M1)):
row = []
for j in range(len(M1[0])):
row.append(M1[i][j]+M2[i][j])
res.append(row)
return res
It works for some input but said:
Test failed for
matrix_sum([[1, 2], [2, 3]], [[4, 2, 1], [1, 2, 3]])
expected output: [],
actual output: [[5, 4], [3, 5]]
How can I change it to work for this also?
Your function checks only that the quantities of rows match; it utterly ignores columns. In fact, if you reverse the mismatched arguments, your function will crash on an index error.
Add another check:
if len(M1) == len(M2) and \
len(M1[0]) == len(M2[0]):
Collect the dimensions first, check if they're valid for element-wise addition, then carry out the addition.
def matrix_sum(M1, M2):
dim_m1, dim_n1 = len(M1), len(M1[0])
dim_m2, dim_n2 = len(M2), len(M2[0])
if dim_m1 != dim_m2 or dim_n1 != dim_n2:
return []
res = [[0 for _ in range(dim_n1)] for _ in range(dim_m1)]
for m in range(dim_m1):
for n in range(dim_n1):
res[m][n] = M1[m][n] + M2[m][n]
return res
This should work (I tested it with your examples). It checks every secondry component:
def matrix_sum(M1, M2):
comp=True
n=0
for i in M1:
if len(i)!=len(M2[n]):
comp=False
n+=1
output=[]
if comp:
n=0
for i in M1:
add=[]
m=0
for j in i:
add.append(j+M2[n][m])
m+=1
n+=1
output.append(add)
return output

Error in converting an array to 2D matrix in Python

I have the problem regarding the output of this algorithm. For example: for input chunk([1, 2, 3, 4, 5, 6, 7, 8], 3) it should return [[ 1, 2, 3], [4, 5, 6], [7, 8, '']] but instead it returns [[7, 8, 6], [7, 8, 6], [7, 8, 6]].
However, when m_list is defined under the loop for r in range(rows):, it returns correct value.
I can't figure out why it returns wrong value if m_list is defined outside the loop for r in range(rows):. What could be the reason ?
# --- Directions
# Given an array and chunk size, divide the array into many subarrays
# where each subarray is of length size
# --- Examples
# chunk([1, 2, 3, 4], 2) --> [[ 1, 2], [3, 4]]
# chunk([1, 2, 3, 4, 5], 2) --> [[ 1, 2], [3, 4], [5, '']]
# chunk([1, 2, 3, 4, 5, 6, 7], 3) --> [[ 1, 2, 3], [4, 5, 6], [7, '', '']]
import math
def chunk (array, size):
rows = 0
l = len(array)
if l % size == 0:
rows = l/size
else:
rows = int(math.floor(l/size) + 1)
m_list = ['' for e in range(size)]
m_matrix = [['' for g in range(size)] for w in range(rows)]
i = 0
for r in range(rows):
for u in range(size):
if i == l:
break
else:
m_list[u] = array[i]
i += 1
m_matrix[r] = m_list
return m_matrix
length = int(raw_input('how many elements you want in the array?: '))
m_inputArray = ['' for q in range(length)]
print 'Debug0:--> ' + str(m_inputArray)
for z in range(length):
p = int(raw_input('Enter the value at index %i: ' %(z)))
m_inputArray[z] = p
m_inputSize = int(raw_input('Enter the size: '))
result = chunk(m_inputArray, m_inputSize)
print result
There are several things wrong with your code. Firstly every loop of u the start value of m_list is the previous list (so the first time it is ['','',''] but the second time it is [1,2,3], and the third time it is [4,5,6]. Which means that since the third time only one value is left in the array, only the first value in the m_list gets redefined, resulting in an m_list of [7,5,6].
Secondly, by saying: m_matrix[u] = m_list you are creating a reference to m_list, you are not copying m_list into m_matrix. This means that once m_list changes, so do the values in m_matrix. Which means in the end you will have defined m_matrix to be [m_list,m_list,m_list], resulting in your results of [[7,5,6],[7,5,6],[7,5,6]]. A solution for this would be to make slice of m_list, like this: m_matrix = m_list[:].
This is how I would do the whole thing:
def chunk(inputarray,size):
array = inputarray[:]
m_matrix = []
while len(array) > 0:
if len(array[:size]) < size:
array.extend(['' for j in range(size-len(array[:size]))])
m_matrix.append(array[:size])
del array[:size]
return m_matrix
If you don't need the original array anymore you can also remove the array = inputarray[:] line of code. Also, probably not the fastest/best way of doing this, but I just wanted to provide something quick. This was done in python 2.7, so if you're using another version you might have to alter some things.
seems a bit over complicated. this is what i came up with.
written for python 3 but does work in 2.
def pop_with_replace(array, index=0, blank=''):
try:
return array.pop(index)
except IndexError:
return blank
def chunk(array, size):
out = []
while array:
t_list = []
for i in range(size):
t_list.append(pop_with_replace(array))
out.append(t_list)
return out
if __name__ == '__main__':
print(chunk(list(range(10)), 3))
there's some things we could change as well. like removing this method pop_with_replace for a ternary operator? i didn't put this in the first solution as they can be awkward to read if not used to them.
t_list.append(array.pop() if array else '')
looking at this we could roll it all up into a list comp. but we're starting to get hard to read.
While array:
out.append([array.pop(0) if array else '' for x in range(size)]
but it does leave the final code looking nice and small.
def chunk(array, size):
out = []
while array:
out.append([array.pop(0) if array else '' for x in range(size)])
return out
In this example there is only one m_list where you update values and final result is [m_list, m_list, m_list ... m_list].
If you define m_list in loop new list will be created in each loop pass.
You can assign directly to m_matrix[r][u] = array[i]
Note that you are with list of lists, not true matrix, and m_matrix[r] = m_list replaces list on r-th position with reference to m_list list.

Categories

Resources