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