Find the first row of a matrix containing all positive elements and the sum of these elements

18

Find the first row of a matrix containing all the positive elements and the sum of these elements. Reduce all elements of this matrix to this sum.

To achieve the required, you should find the array that has all the positive elements, save the index of this array and open another loop to add them. How could I do it, that is, how to find this array and save it?

The objective is to obtain the row of the matrix that has all the positive elements, in this case it would be [7,2,3] and add these elements, which would be 12, and replace all the elements of the matrix with the value of the sum

This is my intent, in this way add all the positive elements.

matrix = [[-5, -6, 2], [7, 2, 3], [8, 4, -9]]

summ = 0
for i in range(len(matrix)):
    pos = False
    for j in range(len(matrix[i])):
        if matrix[i][j] > 0:
            pos = True
            summ += matrix[i][j]

if pos:
    for i in range(len(matrix)):
        for j in range(len(matrix[i])):
            matrix[i][j] = summ
    print("Suma: ", summ)
    for i in matrix:
        print(" ",i)

else:
    print("No hay filas con todos elementos positivos.")
    
asked by Neon 10.01.2016 в 15:22
source

7 answers

10

You could reduce your function like this:

def suma_nasver(matriz):
    resultado = []
    suma = 0
    for arreglo in matriz:
        # Filtramos cada arreglo de la matriz para saber si contiene por lo menos
        # un elemento negativo, si no tiene ninguno se procede a hacer la suma
        elementos_negativos = list(filter(lambda elem: elem < 0, arreglo))
        if not elementos_negativos:
            # Asumo que es la suma de la primera ocurrencia
            suma = sum(arreglo)
            break
    # No es necesario un flag ya que se puede evaluar simplemente el resultado
    # de la suma
    if suma:
        # Si conocemos el largo de la matriz no es necesario iterarla nuevamente
        # para reemplazar los valores, solo usemos una lista vacia
        [resultado.append([suma]) for _ in range(len(matriz))]
    return resultado

Using the function:

>>> suma_nasver([[-5, -6, 2], [7, 2, 3], [8, 4, -9]])
[[12], [12], [12]]
>>> suma_nasver([[-5, -6, -2], [-6, -1, 0], [-4, -4, -1]])
[]
>>> suma_nasver([[-2], [3, 3, 3], [-4], [-9], [-4], [0]])
[[9], [9], [9], [9], [9], [9]]

I hope that the comments have been clear. Some notes:

  • It is not necessary to use the combination range() and len() to iterate an object that in itself is already iterable, simply pass it to the operator in :

    for arreglo in matriz:
        ...
    
  • The filter() function returns a list of items that meet a certain condition, in suma_nasver use to find out if the fix contains any negative element:

    elementos_negativos = filter(lambda elem: elem < 0, arreglo)
    
  • I am using a comprehension list but without saving the result since only I interesting the processing of that part of the code (that's why I also use as a variable%% of%, which tells us that we really do not care about its value):

    [resultado.append([suma]) for _ in range(len(matriz))]
    
  • You did not specify the Python version, but I modified and tested it to work for Python 2 and 3

answered by 10.01.2016 / 17:57
source
9

This is the most pythonic solution that came to my mind:

# Variable que guarda la suma de los numeros positivos por fila
suma_positivos = 0
# Recorremos la matriz fila por fila
for fila in matrix:
    # Verifica si todos los numeros de esta fila son positivos
    if all([numero > 0 for numero in fila]):
            suma_positivos =  sum(fila)
            # Se encontró la fila de positivos, entonces sal del ciclo                
            break

# Si se encontró la fila de positivos, entonces crea la nueva matriz
if suma_positivos:
    new_matrix = [[suma_positivos for value in matrix] for row in matrix]

NOTES

[numero > 0 for numero in fila] is a comprehension list .

p>

What it does is that you create a new list with Boolean values (True / False)

For example

[numero > 0 for numero in [1,2,3]]  # devuelve [True, True, True]
[numero > 0 for numero in [-1,2,3]] # devuelve [False, True, True]

all is a function that returns True if all the elements of the list are true.

For example:

all([True, True, True]) # devuelve True
all([False, True, True]) # devuelve False
    
answered by 10.01.2016 в 18:33
8

In my opinion there are too many "for" loops. Python contains many elements of functional programming that can help solve the problem efficiently (or effectively). In this case:

matrix = [[-5, -6, 2], [7, 2, 3], [8, 4, -9]]
sumallpos = sum(next((x for x in matrix if min(x) > 0), [0]))
if sumallpos:
    matrix = [[sumallpos for x in y] for y in matrix]
else:
    print("No hay filas con todos elementos positivos.")

Using a generator along with next ensures that not all rows in the matrix are analyzed, since it stops when one is found in which all elements are greater than zero min(x) > 0

The resulting matrix in the example:

[[12, 12, 12], [12, 12, 12], [12, 12, 12]]

The use of nested list comprehension ensures that the resulting matrix has the same dimensions as the original, since it iterates over the original elements (if it is more effective to iterate over the elements or over something like range(len(x) is flour from another costal

    
answered by 11.01.2016 в 11:50
6

In summary:

matrix = [[-5, -6, 2], [7, 2, 3], [8, 4, -9]]
sumas = [sum(xs) for xs in matrix if all(x > 0 for x in xs)]
if len(sumas) > 1:
    suma = sumas[0]
    print("Suma: ", suma)
    matrix = [[suma for _ in xs] for xs in matrix]
else:
    print("No hay filas con todos elementos positivos.")
    
answered by 11.01.2016 в 02:12
6

I can think of the following (assuming it is an array and all rows have the same number of columns)

try:
   suma = sum(next(row for row in matrix if all(num>0 for num in row)))
except StopIteration as err:
   # No hay ninguna fila en que todos sean positivos
   pass
else:
   # Esto es posible suponiendo que todas las filas
   # tengan las mismas columnas
   matrix = [[suma]*len(matrix[0])]*len(matrix)
    
answered by 11.01.2016 в 11:35
5

I think this is what you need:

def reemplazar(mat,val):
    for r in range(len(mat)):
        if isinstance(mat[r],list):
            reemplazar(mat[r],val)
        else:
            mat[r]=val



matrix = [[-5, -6, 2], [7, 2, 3], [8, 4, -9]]

summ = 0
for i in range(len(matrix)):
    for j in range(len(matrix[i])):
        if matrix[i][j] >=0:
            summ += matrix[i][j]
        else:
            summ=0
            break #si tiene negativos, lo descarto
    if summ >0:
        print summ
        reemplazar(matrix,summ)
        print(matrix)
        break
else:
   print("No hay filas con todos elementos positivos.")

the replace function in really "raw", only replaces all values in the list and nested lists.

In short, iterate through each list (row), and you add the elements of each, if a row contains a negative value, you stop the sum and continue in the next row. if all the rows have at least one negative value, the else will be executed, indicating the situation.

I did not remember how to do a continue to the top cycle so I used summ as a flag.

    
answered by 10.01.2016 в 18:23
4

I do not know how to python but I'll give you a pseudo code to see if it helps:

summ;
for a = 0; a < columnas.length; a++ {

  int filasCount = 0;
  summ = 0;

 for b = 0; b < filas.length; b++ {

     if array[a][b] > 0 {
      filasCount ++
      summ += matrix[a][b]
     }
 }
  //si lo de debajo se cumple quiere decir que todos son positivos 
  //en esa fila entoces rompemos el for (no se si en python se puede
  //romper el for) para no perder mas tiempo porque usted quiere la
  //primera fila que sea positiva y si tiene 1000 fila y resulta que la
  //primera es positiva no tiene que siguir buscando con lo que ahorra
  //tiempo

  if filasCount == filas.length (los numeros que tienes que mirar) {
    a = columnas.length + 1 (fuerza la salida del for superior)
  }

  //si no entra en el if quiere decir que ahi alguno negativo asi que el
  //contador se pondra a cero para la siguiente fila en la siguiente
  //vuelta junto con summ

 }

Now that you have the result you want in summ you just have to assign it to the whole array, you go through it and assign the summ, if I understand your question well, I think that with the above is enough, but I also tell you that as a python it has lots of library maybe there is some specific for what you are looking for

On the other hand you could use something like that to skip the rows that have negatives.

for b = 0; b < filas.length; b++ {

     if array[a][b] > 0 {
      filasCount ++
      summ += matrix[a][b]
     }else{
     //si entra es que es un numero no valido para ti
     //asi que el entra y nosotros salimos pues esa fila no cumple con lo
     //que pedimos, pues ya uno no es valido

      b = filas.length +1
     }
 }
    
answered by 10.01.2016 в 18:04