-1

I want to check if values in my table's diagonal are equal. How can I do that without checking each diagonal cell? I understand that I can use a loop to do that but I just can't figure out what loop to use.

table = [['1', ' ', '1'],
         [' ', '1', ' '],
         ['1', ' ', '1']]

if tb[0][0] == tb[1][1] == tb[2][2] != ' ' or tb[-1][0] == tb[-2][1] == tb[-3][2] != ' ':
    print(True)
Thulfiqar
  • 393
  • 7
  • 14
danil51608
  • 39
  • 5

3 Answers3

2

Working with arrays and matrices is easiest with numpy. So if this is an option for you, this is how you could go about checking the diagonal of your table:

import numpy as np                                                                                                   
table = [['1', ' ', '1'],                                                                                            
         [' ', '1', ' '],                                                                                            
         ['1', ' ', '1']]                                                                                   
nptable = np.array(table)     
# now we can simply get the unique values in the diagonal:                                                                                                                                                                              
diag_values = np.unique(nptable.diagonal()) 

If you have a single value in diag_values then you know that all diagonal values are equal.

Now if you want to also check the other diagonal, you can use np.fliplr and redo the same:

diag_values = np.unique(np.fliplr(nptable).diagonal()) 

If you want to stick to lists then you could loop over the rows of table until you encounter a change if the value of the diagonal:

diag_val = table[0][0]
for i, row in enumerate(table):
    if row[i] != diag_val:  # row[i] is basically table[i][i]
        print(f'diagonal value changes in row {i=}.')
        break  # we stop the loop as we encoutered a change

Checking the other diagonal is just as easy, simply access the element -i-1 instead of element i in each row:

diag_val = table[0][-1]
for i, row in enumerate(table):
    if row[-i-1] != diag_val:
        print(f'diagonal value changes in row {i=}.')
        break  # we stop the loop as we encoutered a change

Or, if the value in both cases should be the same, say diag_val='1', you can do it in one go:

diag_val = '1'
for i, row in enumerate(table):
    if row[i] != diag_val or row[-i-1] != diag_val:
        print(f'diagonal value changes in row {i=}.')
        break  # we stop the loop as we encoutered a change

Hope that helped!

j-i-l
  • 10,281
  • 3
  • 53
  • 70
0

you can use numpy.diagonal() to get all the elements whether on the first or the second diagonal and then compare all the elements to satisfy the condition using numpy.all()

import numpy as np

mtx = np.array([['2', ' ', '1'],
                [' ', '1', ' '],
                ['1', ' ', '3']])


first_diag = mtx.diagonal()
second_diag = (np.fliplr(mtx)).diagonal()

result = np.all(second_diag == '1')

if result:
    print("all the elements in the diagonal are equal to one")
else:
    print("not all elements in the diagonal are equal")
Thulfiqar
  • 393
  • 7
  • 14
0

One way is to do this is to extract the values of both diagonals as sets and then check if: a) the sets are equal and b) their size is 1.

main_diag = {row[ i] for i, row in enumerate(tb)}
anti_diag = {row[-i] for i, row in enumerate(tb, start=1)}

if main_diag == anti_diag and len(main_diag) == 1:
    print('All values along both diagonals are the same.')
folkol
  • 4,752
  • 22
  • 25
  • The type of `main_diag` is `set`, created by the `set comprehension` on the right hand side. The set comprehension can be interpreted like a for loop that loops over `enumerate(tb)` and then adds `row[i]` to the to-be-constructed set. – folkol Mar 27 '21 at 16:04