Python - алгоритм для определения симметричности списка

Так что я застрял в этой проблеме, когда меня попросили написать функцию на Python, которая проверяет, является ли n-мерный массив (это то, что они называют?) "Симметричным" или нет, то есть эта строка 1 массива == столбец 1, строка 2 == столбец 2, строка 3 == столбец 3 и т. Д. И т. Д. И т. Д. Цель состоит в том, чтобы иметь функцию, которая возвращает логическое значение True, если оно симметричное, и False, если нет.

Мне удалось написать функцию, которая работает, но она работает только со списками, размеры которых являются идеальными квадратами (например, 2 x 2, 4 x 4), и некоторые из моих тестовых случаев имеют "неправильные" размеры (например, 2 х 5, 3 х 2). Для этих списков я получаю индекс списка вне диапазона. Код ошибки здесь:

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

И тестовые случаи, которые я проваливаю здесь:

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

Может кто-нибудь помочь мне изменить код так, чтобы он работал на этих массивах "неправильной формы"?

6 ответов

Решение

Вы можете поставить эту проверку в начале вашей функции:

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

Или может быть короче

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

Этот фрагмент кода сделает все за вас:

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

В своем решении вы выполняете слишком много работы самостоятельно. Python будет сравнивать последовательности для вас, поэтому более простой метод состоит в том, чтобы транспонировать квадрат так, чтобы его строки становились столбцами, и наоборот, а затем сравнивать его с исходным значением.

Мы можем транспонировать квадрат, используя функцию zip. Это принимает несколько последовательностей и возвращает кортеж, содержащий сначала каждый из них, а затем кортеж со вторым каждым и так далее. Мимоходом square как *square мы передаем каждую строку в качестве отдельного аргумента; это имеет эффект транспонирования квадрата.

Единственное осложнение состоит в том, что zip возвращает кортежи, а не списки, поэтому мы должны убедиться, square это список кортежей, поэтому сравнение работает.

Вот альтернативная версия для основного теста:

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

Конечно, все остальные ответы, которые советуют вам проверить, является ли матрица квадратной, верны.

Версия для Python3

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

Значение y = 0 должен быть внутри первого цикла while. Как это:

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

Добавьте это в начале:

for row in square:
    if len(row) != len(square):
        return False
Другие вопросы по тегам