How to make a matrix that only holds None values? - python

I have to write a function empty_matrix that must return a list of lists (a matrix)
desired output:
empty_matrix(3,4)
returns a list with three lists each of length four:
[[None,None,None,None],[None,None,None,None],[None,None,None,None]]
What should I change in my code below???
def empty_matrix(row,column):
first_col = []
for x in range(len(matrix)):
sublist = matrix[x]
for y in range(len(sublist)):
first_col.append(matrix[x][y])

Using a list comprehension:
def empty_matrix(row, column):
return [[None for _ in range(row)] for _ in range(column)]
But to fix your code, you're using len on variables matrix and sublist that aren't defined, your indentation is off, try something like this if you don't want to use a list comprehension.
def empty_matrix(row, column):
matrix = []
for c in range(column):
column = []
for r in range(row):
column.append(None)
matrix.append(column)
return matrix

Related

Can anyone explain what am i doing wrong

Question:-Write a Python function transpose(m) that takes as input a two dimensional matrix m and returns the transpose of m. The argument m should remain undisturbed by the function.
def transpose(l):
m=l[:]
lst=[[] for x in range(len(m[0)]
for i in range(0,len(m)):
for j in range(0,len(m[i])):
lst[j].append(m[i][j])
return lst
l=[[1,2,3,4,5],[4,5,6,7,8,9]]
ERROR
lst[j].append(m[i][j])
IndexError: list index out of range
Your List l has two lists with 5 and 6 elements.
So, the range of j in range(len(m[1])) is 0 - 5 (6 numbers), which results in index out of range for lst (which only have 5 elements).
def transpose(l):
lst=[[] for x in range(len(l[0]))]
for i in range(len(l)):
for j in range(len(l[i])):
lst[j].append(l[i][j])
return lst
l = [[1,2,3,4,5],[4,5,6,7,8]]
But I would add a checking part at the beginning of the function
def transpose(l):
iterator = iter(l)
lists_len = len(next(iterator))
if not all(len(a) == lists_len for a in iterator):
# Do something here
lst=[[] for x in range(len(l[0]))]
for i in range(len(l)):
for j in range(len(l[i])):
lst[j].append(l[i][j])
return lst

Swapping columns of a matrix without numpy

I need to swap the columns of a given matrix by applying some function to (M,i,j) to swap the ith and jth columns of M.
def swap_columns(M,i,j)
rows = M[i]
col = M[i][j]
for i in M:
N = M[i][j]
M[i][j] = M[j][i]
M[j][i] = N
return N
Unable to get this working at all.
In python variable swapping can be done by: x, y = y, x
Code:
This function will modify the original matrix. No need to return
def col_swapper(matrix, col_1, col_2):
for line in range(len(matrix)):
matrix[line][col_1], matrix[line][col_2] = matrix[line][col_2], matrix[line][col_1]
You could do it (in-place) using a for-loop to perform the swapping through unpacking of the matrix's rows:
def swapCols(M,c1,c2):
for row,row[c2],row[c1] in ((row,row[c1],row[c2]) for row in M):pass
you can use this function:
import copy
def my_swap(M, i, j):
temp = copy.deepcopy(M)
for k in range(len(M)):
temp[k][i] = M[k][j]
temp[k][j] = M[k][i]
return temp

Have to define a function that can find the averages of multiple list of list in python

I have made list of list, now I want to define a function that can calculate the averages of each list. I have made a function, but it only works for the list that is on first index. How can I make it run for all lists
def final_list(x):
average=list(map(int, final_list[x]))
sum_list = sum(average)
len_list = len(average)
average_final = sum_list/len_list
You can use a list comprehension to compute the average for each sublist
def average(x):
return sum(x) / len(x)
def final_list(lists):
return [average(x) for x in lists]
hey you mean somthing like this?
import random
def array_avg(array):
for lst in array:
length = len(lst)
average = sum(lst) / length
print(f"list average = {average}")
if __name__ == '__main__':
arr = [[c for c in range(1, random.randint(2, 10))] for i in range(5)]
array_avg(arr)

Adding matrix elements as the nested lists by list comprehension (and zip) in Python

I've tried to proceed with adding the matrix elements of 2 matrices by
using list comprehension and zip, as I thought it would be so simple to perform. Unfortunately, and I've tried to do this in the proverbial "overly clever" way and I failed. I still don't understand where I've made a mistake and exercising my brain in complex comprehension structures is the piece of training I miss.
The code by which I tried to perform adding of 2 matrices in the form of nested lists:
Example input at the def main():
It looks like this fragment produces major error:
new_matrix[index] = zip(row, other[index])
IndexError: list assignment index out of range
class Matrix:
def __init__(self, matrix):
self.matrix = matrix
def add(self,number_of_rows, number_of_columns, other):
new_matrix = [[] * len(self.matrix)]
if len(self.matrix) == len(other) and len(self.matrix[0]) == len(other[0]):
for index, row in enumerate(self.matrix):
new_matrix[index] = zip(row, other[index])
return [[x + y for (x, y) in new_matrix[index]] for index in range(0, len(new_matrix))]
def main():
matrix1 = Matrix([[1,2,3], [2,3,4],[4,5,6]])
matrix2 = matrix1.add([[1,2,3],[2,3,4],[4,5,6]])
print(matrix2)
if __name__ == '__main__':
main()
The problem is new_matrix = [[] * len(self.matrix)]
I assume you expect is that [[] * 3] will give:
[[], [], []] but it is not.
[]*N is just [] for every N
so your new_matrix is list with only ONE element which is [] and when you try to assign to new_matrix[1] you get your error.
Instead perform:
new_matrix = [[]] * len(self.matrix)
I haven't tested the rest of your code
update - checked your example with my fix and it is working

How to write this program into a for loop?

I'm trying to learn how to change this program into a for loop for the sake of knowing both ways
def Diff(a_list):
num = enumerate(max(x) - min(x) for x in a_list)
return max(x[::-1] for x in num)
I want it to be something like
def Diff(x):
for a in x
if it helps the program is intended to return the row that has the smallest sum of the elements inside it so like [[1,2,3,4],[-500],[10,20]] would be 1.
I do not understand why you use this name for your function, it does something else (as far as I understand). It searches for the inner-list inside a list for which the difference between min and max, the span, are maximal and the n returns a tuple (span, idx), idx being the index within the outer loop.
When you want to have the same as a loop, try:
def minRow_loop(a_list):
rv = (0,0)
for idx, row in enumerate(a_list):
span = max(row) - min(row)
span_and_idx = (span, idx)
if span_and_idx > rv:
rv = span_and_idx
return rv
But your code doesn't do what it'S intended to do, so I created two correct versions, once with and once without a loop.
import random
random.seed(12346)
def minRow(a_list):
num = enumerate(max(x) - min(x) for x in a_list)
return max(x[::-1] for x in num)
def minRow_loop(a_list):
rv = (0,0)
for idx, row in enumerate(a_list):
span = max(row) - min(row)
span_and_idx = (span, idx)
if span_and_idx > rv:
rv = span_and_idx
return rv
def minRow_correct(a_list):
return min(enumerate([sum(l) for l in a_list]),
key=lambda (idx, val): val)[0]
def minRow_correct_loop(a_list):
min_idx = 0
min_sum = 10e50
for idx, list_ in enumerate(a_list):
sum_ = sum(list_)
if sum_<min_sum:
min_idx = idx
min_sum = sum
return min_idx
li = [[random.random() for i in range(2)] for j in range(3)]
from pprint import pprint
print "Input:"
pprint(li)
print "\nWrong versions"
print minRow(li)
print minRow_loop(li)
which prints:
Input:
[[0.46318380478657073, 0.7396007585882016],
[0.38778699106140135, 0.7078233515518557],
[0.7453097328344933, 0.23853757442660117]]
Wrong versions
(0.5067721584078921, 2)
(0.5067721584078921, 2)
Corrected versions
2
2
What you want can actually be done in two lines of code:
# Let's take the list from your example
lst = [[1,2,3,4],[-500],[10,20]]
# Create a new list holding the sums of each sublist using a list comprehension
sums = [sum(sublst) for sublst in lst]
# Get the index of the smallest element
sums.index(min(sums)) # Returns: 1
if you're looking for minimum sum, just go through every row and keep track of the smallest:
def minRow(theList):
foundIndex = 0 # assume first element is the answer for now.
minimumSum = sum(theList[0])
for index, row in enumerate(theList):
if sum(row) < minimumSum:
foundIndex = index
minimumSum = sum(row) # you don't have to sum() twice, but it looks cleaner
return foundIndex
If your looking for greatest range (like the first Diff() function), it'd be similar. You'd keep track of the greatest range and return its index.
Thorsten's answer is very complete. But since I finished this anyway, I'm submitting my "dumbed down" version in case it helps you understand.

Categories

Resources