Учтите, что есть несколько списков целых чисел:
#--------------------------------------
0 [0,1,3]
1 [1,0,3,4,5,10,...]
2 [2,8]
3 [3,1,0,...]
...
n []
#--------------------------------------
Вопрос состоит в том, чтобы объединить списки, имеющие хотя бы один общий элемент.Таким образом, результаты только для данной части будут следующими:
#--------------------------------------
0 [0,1,3,4,5,10,...]
2 [2,8]
#--------------------------------------
Какой самый эффективный способ сделать это для больших данных (элементы - просто числа)? Является ли tree
структурировать что-то для размышления?Я делаю работу сейчас, преобразовывая списки в sets
и повторяя для пересечений, но это медленно!Кроме того, у меня такое ощущение, что это так элементарно!Кроме того, в реализации чего-то не хватает (неизвестно), потому что некоторые списки иногда остаются не объединенными!Сказав это, если вы предлагаете самореализацию, пожалуйста, будьте щедрыми и предоставьте простой пример кода [очевидно, Python - мой фаворит :)] или псевдокод.
Обновление 1: Вот код, который я использовал:
#--------------------------------------
lsts = [[0,1,3],
[1,0,3,4,5,10,11],
[2,8],
[3,1,0,16]];
#--------------------------------------
Функция ( глючит !! ):
#--------------------------------------
def merge(lsts):
sts = [set(l) for l in lsts]
i = 0
while i < len(sts):
j = i+1
while j < len(sts):
if len(sts[i].intersection(sts[j])) > 0:
sts[i] = sts[i].union(sts[j])
sts.pop(j)
else: j += 1 #---corrected
i += 1
lst = [list(s) for s in sts]
return lst
#--------------------------------------
Результат:
#--------------------------------------
>>> merge(lsts)
>>> [0, 1, 3, 4, 5, 10, 11, 16], [8, 2]]
#--------------------------------------
Обновление 2: По моему опыту код, приведенный ниже Niklas Baumstark , показался немного быстрее для простых случаев.Еще не проверен метод, данный «Крючком», поскольку это совершенно другой подход (кстати, он кажется интересным).Процедура тестирования для всего этого может быть очень трудной или невозможной для обеспечения результатов.Реальный набор данных, который я буду использовать, настолько велик и сложен, что невозможно отследить любую ошибку, просто повторив.То есть я должен быть на 100% удовлетворен надежностью метода, прежде чем поместить его на место в большом коде в качестве модуля.Просто пока Niklas метод быстрее, и ответ для простых наборов, конечно, правильный.
Однако как я могу быть уверен, что он работает хорошо для действительно большого набора данных? Поскольку я не смогу визуально отследить ошибки!
Обновление 3: Обратите внимание, что надежность метода гораздо важнее, чем скорость для этой проблемы.Я надеюсь, что смогу наконец-то перевести код Python в Fortran для максимальной производительности.
Обновление 4:
В этом посте есть много интересных моментов и щедро предоставленных ответов, конструктивныхКомментарии.Я бы рекомендовал прочитать все внимательно.Пожалуйста, примите мою благодарность за разработку вопроса, удивительные ответы и конструктивные комментарии и обсуждение.