Существует простое решение: 1) подсчитать количество элементов в каждом столбце, 2) использовать это количество для построения другого списка.
from collections import Counter
mat = [[1,3,5,7], [1,2,5,7], [8,2,3,4]]
col_counts = [Counter(col) for col in zip(*mat)]
results = [[count[cell] for cell, count in zip(row, col_counts)] for row in mat]
Результат:
[[2, 1, 2, 2], [2, 2, 2, 2], [1, 2, 1, 1]]
Обратите внимание, что в первой строке [1,3,5,7]
элемент 3
соответствует 1
, а не нулю, поскольку у вас ровно один3
во втором столбце [3, 2, 2]
.
Немного более легкое решение (используется только один счетчик за раз), я также детализировал построчное преобразование, чтобы его было легче понять:
def row_count(mat):
def row_transform(row):
count = Counter(row)
return [count[e] for e in row]
matT = zip(*mat)
matT_count = map(row_transform, matT)
return zip(*matT_count)
Если вам нужен список, то вы можете вызвать list(row_count(mat))
, если вам нужно только перебрать строки, вы можете сделать for row in row_count(mat):
, и это сэкономит вам немного памяти (создание только одной строки за раз).