3x3 Matrix not printing in correct format - python

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)

Related

Multiplying elements of a matrix with an integer to create a new matrix

I have a matrix M, for which I need to return a tuple (i,j) which gives me the index (row,column) of the first maximum value in the matrix.
Tried this, but gives me a type error that int is not iterable.
Would be very grateful for your help / advice on this.
def matrix_max_index(M):
m=len(M)
n=len(M[0])
for i in range(0,m):
for j in range (0,n):
if M[i][j] == max(M[i][j]):
return (i,j)
for example: if input is M = [[0, 3, 2, 4], [2, 3, 5, 5], [5, 1, 2, 3]] returns (1,2)
The following will work:
def matrix_max_index(M):
m_val = coords = None
for r, row in enumerate(M):
for c, val in enumerate(row):
if m_val is None or val > m_val:
m_val = val
coords = r, c
return coords
You have to keep track of the current maximum and update maximum value and coordinates as necessary. You can only return at the end once you have visited all cells.
Some docs:
enumerate
Use max to find the overall maximum and then next to find the first coordinate matching it:
def matrix_max_index(M):
# find the overall maximum
ma = max(e for row in M for e in row)
# find the first matching value
res = next((i, j) for i, row in enumerate(M) for j, e in enumerate(row) if e == ma)
return res
M = [[0, 3, 2, 4], [2, 3, 5, 5], [5, 1, 2, 3]]
print(matrix_max_index(M))
Output
(1, 2)
As an alternative use the key parameter of max to map the indices to their corresponding value and pick the one with the maximum:
def matrix_max_index(M):
rows = len(M)
cols = len(M[0])
res = max(((i, j) for i in range(rows) for j in range(cols)), key=lambda x: M[x[0]][x[1]])
return res

how to fill matrix using range without numpy?

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)

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.

Python Array Rotation

So I am implementing a block swap algorithm in python.
The algorithm I am following is this:
Initialize A = arr[0..d-1] and B = arr[d..n-1]
1) Do following until size of A is equal to size of B
a) If A is shorter, divide B into Bl and Br such that Br is of same
length as A. Swap A and Br to change ABlBr into BrBlA. Now A
is at its final place, so recur on pieces of B.
b) If A is longer, divide A into Al and Ar such that Al is of same
length as B Swap Al and B to change AlArB into BArAl. Now B
is at its final place, so recur on pieces of A.
2) Finally when A and B are of equal size, block swap them.
The same algorithm has been implemented in C on this website - Array Rotation
My python code for the same is
a = [1,2,3,4,5,6,7,8]
x = 2
n = len(a)
def rotate(a,x):
n = len(a)
if x == 0 or x == n:
return a
if x == n -x:
print(a)
for i in range(x):
a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
print(a)
return a
if x < n-x:
print(a)
for i in range(x):
a[i], a[(i-x+n) % n] = a[(i-x+n) % n], a[i]
print(a)
rotate(a[:n-x],x)
else:
print(a)
for i in range(n-x):
a[i], a[(i-(n-x) + n) % n] = a[(i-(n-x) + n) % n] , a[i]
print(a)
rotate(a[n-x:], n-x)
rotate(a,x)
print(a)
I am getting the right values at each stage but the recursive function call is not returning the expected result and I cannot seem to understand the cause. Can someone explain whats wrong with my recursion ? and what can be the possible alternative.
You can rotate a list in place in Python by using a deque:
>>> from collections import deque
>>> d=deque([1,2,3,4,5])
>>> d
deque([1, 2, 3, 4, 5])
>>> d.rotate(2)
>>> d
deque([4, 5, 1, 2, 3])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5])
Or with list slices:
>>> li=[1,2,3,4,5]
>>> li[2:]+li[:2]
[3, 4, 5, 1, 2]
>>> li[-2:]+li[:-2]
[4, 5, 1, 2, 3]
Note that the sign convention is opposite with deque.rotate vs slices.
If you want a function that has the same sign convention:
def rotate(l, y=1):
if len(l) == 0:
return l
y = -y % len(l) # flip rotation direction
return l[y:] + l[:y]
>>> rotate([1,2,3,4,5],2)
[4, 5, 1, 2, 3]
>>> rotate([1,2,3,4,5],-22)
[3, 4, 5, 1, 2]
>>> rotate('abcdefg',3)
'efgabcd'
For numpy, just use np.roll
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> np.roll(a, 1)
array([9, 0, 1, 2, 3, 4, 5, 6, 7, 8])
>>> np.roll(a, -1)
array([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
Or you can use a numpy version of the same rotate above (again noting the difference in sign vs np.roll):
def rotate(a,n=1):
if len(a) == 0:
return a
n = -n % len(a) # flip rotation direction
return np.concatenate((a[n:],a[:n]))
A simple and shorthand syntax for array rotation in Python is
arr = arr[numOfRotations:]+arr[:numOfRotations]
Example:
arr = [1,2,3,4,5]
rotations = 4
then
arr = arr[4:]+arr[:4]
gives us
[5,1,2,3,4]
I found a problem that I needed Right and Left rotations for big values of k (where k is number of rotations), so, I implemented the following functions for any size of k.
Right Circular Rotation (left to the right: 1234 -> 4123):
def right_rotation(a, k):
# if the size of k > len(a), rotate only necessary with
# module of the division
rotations = k % len(a)
return a[-rotations:] + a[:-rotations]
Left Circular Rotation (right to the left: 1234 -> 2341):
def left_rotation(a, k):
# if the size of k > len(a), rotate only necessary with
# module of the division
rotations = k % len(a)
return a[rotations:] + a[:rotations]
Sources:
https://stackoverflow.com/a/46846544/7468664
https://stackoverflow.com/a/9457923/7468664
Do you actually need to implement the block swap or are you just looking to rotate the array? In python you can do CW and CWW rotations using
zip(*arr[::-1])
and
zip(*arr)[::-1]
I expect that when you pass a slice of a to your recursive call, you're not passing the same variable any more. Try passing a in its entirety and the upper / lower bounds of your slice as additional arguments to your function.
For instance consider this function:
def silly(z):
z[0] = 2
I just tried the following:
>>> z = [9,9,9,9,9,9]
>>> silly(z)
>>> z
[2, 9, 9, 9, 9, 9]
>>> silly(z[3:])
>>> z
[2, 9, 9, 9, 9, 9]
Where you can see the modification to the slice was not retained by the full array
Out of curiosity, what outputs do you get & what outputs do you expect?
you can use this code for left rotation in python array
import copy
def leftRotate(arr,n) :
_arr = copy.deepcopy(arr)
for i in range(len(arr)-n):
arr[i] = arr[i+n]
for j in range(n):
arr[(len(arr)-n)+j] = _arr[j]
arr = [1, 2, 3, 4, 5, 6, 7]
leftRotateby = 3
leftRotate(arr,leftRotateby)
print arr
#output:: [4, 5, 6, 7, 1, 2, 3]
def leftRotation():
li = [int(x) for x in input().split()]
d = int(input())
ans = (li[d:]+li[0:d])
for i in ans:
print(i,end=' ')
print()
leftRotation()
def rotLeft(a, d):
lenght=len(a)
for j in range(0,d):
temp = a[0]
for i in range(lenght-1):
a[i] = a[i+1]
a[lenght-1] = temp
# Write your code here
return a
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
first_multiple_input = input().rstrip().split()
n = int(first_multiple_input[0])
d = int(first_multiple_input[1])
a = list(map(int, input().rstrip().split()))
result = rotLeft(a, d)
fptr.write(' '.join(map(str, result)))
fptr.write('\n')
fptr.close()
Array Rotation:-
print("Right:1,Left:2")
op=int(input())
par=[1,2]
if op not in par:
print("Invalid Input!!")
else:
arr=list(map(int,input().strip().split()))
shift=int(input())
if op ==1:
right=arr[-shift:]+arr[:-shift]
print(right)
elif op==2:
left=arr[shift:]+arr[:shift]
print(left)
Ouput:-`
Right:1,Left:2
1
12 45 78 91 72 64 62 43
2
[62, 43, 12, 45, 78, 91, 72, 64]`
def rotate(nums=[1,2,3,4,5,6,7], k=3):
i=0
while i < k:
pop_item = nums.pop()
nums.insert(0, pop_item)
i += 1
return nums # [5,6,7,1,2,3,4]
If you are not supposed to use deque or slicing:
def rotate(array: List[int], k: int) -> List[int]:
# loop through the array from -k to array_size - k
return [array[i] for i in range(-k, len(array) - k)]
def rotate(nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: None Do not return anything, modify nums in-place instead.
"""
result = []
if len(nums) <= 1 : return nums
if k > len(nums): k = K % len(nums)
for i in range(k):
result.insert(0,nums[-1])
nums.pop()
nums = result + nums
return nums
Here, I've used the method of swapping using a temporary variable to rotate an array. As an example, an array 'a' of size 5 is considered. Two variables 'j' and 'i' are used for outer and inner loop iterations respectively. 'c' is the temporary variable. Initially, the 1st element in the array is swapped with the last element in the array i.e a=[5,2,3,4,1]. Then, the 2nd element is swapped with the current last element i.e in this case 2 and 1. At present, the array 'a' would be a=[5,1,3,4,2]. This continues till it reaches the second last element in the array. Hence, if the size of the array is n (5 in this case), then n-1 iterations are done to rotate the array. To enter the no of times the rotation must be done, m is given a value with which the outer loop is run by comparing it with the value of j.
Note: The rotation of array is towards the left in this case
a=[1,2,3,4,5]
n=len(a)
m=int(input('Enter the no of rotations:'))
j=0
while(j<m):
i=0
while(i<n):
c=a[i]
a[i]=a[n-1]
a[n-1]=c
i=i+1
j=j+1
print(a)

Categories

Resources