简体   繁体   中英

Python - Algorithm to determine if a list is symmetric

So I'm stuck on this problem where I've been asked to write an function in Python that checks to see if an n-dimensional array (is that what they're called?) is "symmetric" or not, meaning that row 1 of the array == column 1, row 2 == column 2, row 3 == column 3, etc so on and so forth. The goal is to have a function that returns the boolean True if its symmetric, and False if its not.

I've managed to write a function that works, but it only work on lists whose sizes are perfect squares, (eg 2 x 2, 4 x 4), and a few of my test cases are of "irregular" sizes (eg 2 x 5, 3 x 2). For those lists I end up getting a list index out of range error Code here:

def symmetric(square):
    final_result = []
    x = 0
    y = 0
    while x < len(square):
        row_list = []
        col_list = []
        while y < len(square[x]):
            print "(x, y): %d, %d" % (x, y)
            print "(y, x): %d, %d" % (y, x)
            row_list.append(square[x][y])
            col_list.append(square[y][x])
            y = y + 1
        if row_list == col_list:
            final_result.append(True)
        else:
            final_result.append(False)
        x = x + 1

    for x in final_result:
        if x == False:
            return False
    return True

And the test cases that I'm failing on here:

print symmetric([[1, 2, 3, 4],
                [2, 3, 4, 5],
                [3, 4, 5, 6]])
#Expected result: >>> False
#List index out of range

# This one actually returns the correct result, I'm just including it here
# for reference.
#print symmetric([["cat", "dog", "fish"],
#                ["dog", "dog", "fish"],
#                ["fish", "fish", "cat"]])
#Expected result: >>> True
#Actual result: >>> True


print symmetric([[1,2,3],
                 [2,3,1]])
#Expected Result: >>> False
#Actual result: list index out of range

Can someone help me modify the code so that it will work on these "irregularly shaped" arrays?

This bit of code will do it all for you:

def symmetric(square):
    square = [tuple(row) for row in square]
    return square == zip(*square)

In your solution you're doing too much of the work yourself. Python will compare sequences for you, so an easier method is to transpose the square so its rows become columns and vice versa and then compare it to the original value.

We can transpose the square using the zip function . This takes a number of sequences and returns a tuple containing first of each and then a tuple with the second of each and so on. By passing square as *square we pass each row as a sperate argument; this has the effect of transposing the square.

The only complication is that zip returns tuples not lists so we have to make sure square is a list of tuples so the comparison works.

You can put this check at the start of your function:

for row in square:
    if len(row) != len(square):
        return False

Or maybe shorter

if not all(len(square) == len(row) for row in square): return False

Here's an alternative version for the main test:

for i, line in enumerate(matrix):
    for j in range(len(line)):
        if a[i][j] != a[j][i]:
             return False
return True

Of course that all the other answers that advise you to test if the matrix is square hold true.

Add this near the beginning:

for row in square:
    if len(row) != len(square):
        return False

A version for Python3

def symmetric(L)
    return all(i==j for i,*j in zip(L ,*L))

Value y = 0 should be inside the first while loop. Like this:

def symmetric(square):
    final_result = []
    x = 0
    while x < len(square):
         y = 0
        row_list = []
        .
        .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM