Оптимизированная версия решения Tomothys :
отсортировано (list1, ключ = лямбда-элемент: сумма ([list1.index (элемент), list2.index (элемент), list3.index (элемент)]) / 3)
вызывает .index()
3 раза для каждого элемента list1
- каждый вызов повторяет соответствующий список (для каждого элемента в list1), пока не найдет событие - в итоге вы получите что-то вроде sum([1,2,3,4,5,6])
три раза, что 63
(вместо 18
- см. Ниже).
Сложность моего решения определяется O(n)
, где n = sum(len(item) for item in data) => 18
- сложность сортировки незначительна, поскольку она работает только с set()
элементов во всех списках, что намного меньше. сложность Timsort потребности (наихудший случай) O(m*log(m))
где m = set(i for sub in data for i in sub) => 6
from collections import defaultdict
data = [['A', 'D', 'GE', 'G', 'M', 'S'], ['A', 'D', 'M', 'G', 'S', 'GE'],
['D', 'M', 'A', 'S', 'G', 'GE']]
d = defaultdict(list) # or int and use /3.0 implicitly
# this loop touches each element once: O(n) n = sum(length of all lists)
for l in data:
for idx,value in enumerate(l):
d[value].append(idx)
# timsort: O(m) to O(m*log(m)) for the much shorter set() over emelents of all lists)
# sort by score:
result = sorted(d.items(), key= lambda x:sum(x[1])/float(len(x[1])))
print( *(r for r in result), sep="\n") # use 'r[0] for r ..' to just print the names
Выход:
('A', [0, 0, 2])
('D', [1, 1, 0])
('M', [4, 2, 1])
('G', [3, 3, 4])
('GE', [2, 5, 5])
('S', [5, 4, 3])
Если вы гарантируете, что каждый подсписок содержит одинаковые элементы - просто в другом порядке, вы можете еще больше упростить:
d = defaultdict(int)
# this loop touches each element once: O(n)
for l in data:
for idx,value in enumerate(l):
d[value]+=idx
# there is no sense in dividing the sum by 3 if _all_ sums have to be devided by it
# sort by score:
result = sorted(d.items())
print( *(r for r in result), sep="\n")
Выход:
('A', 2)
('D', 2)
('G', 10)
('GE', 12)
('M', 7)
('S', 12)
defaultdict
быстрее, чем обычные диктовки - но если вы не любите импортировать, вы можете изменить его на более медленный
d = {}
d.setdefault(key, []).append(value) # defaultdict(list)
d.setdefault(key, 0) += value # defaultdict(int)
setdefault(key,default)
медленнее, потому что он всегда создает default
, что требует времени - defaultdict (...) оптимизирован, чтобы не нуждаться в этом, и поэтому (немного) быстрее.