Вывести цвет, который максимальное количество раз идет подряд, либо в ряде, либо в столбце
Есть двумерный список:
color_chains = [
["green", "yellow", "blue", "red", "green"],
["green", "yellow", "blue", "red", "yellow"],
["blue", "yellow", "blue", "blue", "blue"],
["green", "yellow", "red", "red", "red"]
]
В данном случает ответ должен быть yellow.
Я решил эту задачу так:
def count_max_chain(chain_of_colors):
max_count_same_color_row = 1
count_same_color_row = 1
max_count_same_color_column = 1
count_same_color_column = 1
previous_color = None
row_result = {}
column_result = {}
# самое длинное в ряде
for row in chain_of_colors:
for color in row:
if color == previous_color:
count_same_color_row += 1
else:
previous_color = color
count_same_color_row = 1
if count_same_color_row > max_count_same_color_row:
max_count_same_color_row = count_same_color_row
row_result = {color: max_count_same_color_row}
count_same_color_row = 1
# самое длинное в колонне
max_len_row = 0
previous_color = None
index_color = 0
for row in chain_of_colors:
if len(row) > max_len_row: max_len_row = len(row)
while index_color <= max_len_row:
for row in chain_of_colors:
try:
if row[index_color] == previous_color:
count_same_color_column += 1
if count_same_color_column > max_count_same_color_column:
column_result = {}
max_count_same_color_column = count_same_color_column
column_result[row[index_color]] = max_count_same_color_column
else:
previous_color = row[index_color]
count_same_color_column = 1
except:
pass
index_color += 1
if max_count_same_color_column > max_count_same_color_row:
print(column_result)
else:
print(row_result)
count_max_chain(color_chains)
Но уверен, что есть более изящный метод. Можете его подсказать, пожалуйста?
Ответы (1 шт):
Не знаю насколько это "изящно", но, как вариант, можно вот так:
from itertools import chain, zip_longest
color_chains = [["green", "yellow", "blue", "red" , "green" ],
["green", "yellow", "blue", "red" , "yellow"],
["blue" , "yellow", "blue", "blue", "blue" ],
["green", "yellow", "red" , "red" , "red" ]]
def count_max_chain(chain_of_colors):
def max_chain_in_row(row):
res = []
for item in row:
res.append((res[-1][0]+1, item) if res and res[-1][1] == item else (1,item))
return max(res)
return max(max_chain_in_row(row) for row in chain(chain_of_colors, zip(*chain_of_colors)))[1]
print(count_max_chain(color_chains))
Функция max_chain_in_row(row) обрабатывает ряд и подсчитывает в нём повторяющиеся элементы. Например, для нижеприведённого ряда будет такое преобразование:
["blue" , "yellow", "blue", "blue", "blue"]
v v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
[(1,"blue") , (1,"yellow"), (1,"blue"), (2,"blue"), (3,"blue")].
И в конце возвращает кортеж с максимальным значением.
Ну а общая функция собирает в общий список результаты обработки рядов исходного списка списков плюс рядов транспонированной матрицы zip(*chain_of_colors) (это исходный список где столбцы стали рядами и наоборот (чтобы не заморачиваться и всегда работать с рядами) и опять берёт максимум.
(Если в конце последнего return убрать [1], то функция вернёт кортеж (количество, цвет).)
Если ряды могут быть не одинаковой длины, то с минимальными модификациями функция будет выглядеть так:
def count_max_chain(chain_of_colors):
def max_chain_in_row(row):
res = []
for item in row:
res.append((res[-1][0]+1, item) if item and res and res[-1][1] == item else res[-1] if item is None else (1,item))
return max(res)
return max(max_chain_in_row(row) for row in chain(chain_of_colors, zip_longest(*chain_of_colors)))[1]