пересечение кортежей в списке - python

1

У меня есть список таких кортежей:

all_tuples=[(92, 242),(355, 403),(355, 436),(355, 489),(403, 436),(436, 489),(515, 517),(517, 859),(634, 775),(701, 859),(775, 859)]

и мне нужно пересечь все кортежи и объединить их.

The desired result = [{92, 242},{355, 403,436,489},{515, 517,859,701,775,634}]

То есть пересекающиеся кортежи объединяются итеративно.

Я попытался преобразовать кортежи в наборы, а затем пересечь, но не получилось. Любая идея?

Теги:
python-3.x
set

3 ответа

3
Лучший ответ

Это проблема сети с использованием networkx

import networkx as nx 
G=nx.Graph()
all_tuples=[(92, 242),(355, 403),(355, 436),(355, 489),(403, 436),(436, 489),(515, 517),(517, 859),(634, 775),(701, 859),(775, 859)]
G.add_edges_from(all_tuples)
list(nx.connected_components(G))
Out[1216]: [{92, 242}, {355, 403, 436, 489}, {515, 517, 634, 701, 775, 859}]
  • 0
    Вау, никогда не думал об этом как о проблеме с сетью. Этот ответ заставил меня переосмыслить решение других сложных проблем в моем текущем проекте. Я хотел бы принять оба ответа, но выполнение этих ответов происходит быстрее. Спасибо
  • 0
    @nlp_practitioner не беспокойся, вот почему мы здесь, не так ли? :-)
Показать ещё 1 комментарий
1

Это решение строит список классов эквивалентности, где нахождение в одном кортеже является нашим отношением эквивалентности. Для каждого кортежа мы составляем список всех наборов в нашем списке, которые соответствуют некоторому элементу этого кортежа. Если его нет, мы делаем набор этого кортежа и добавляем его в список. Если он есть, мы обновляем этот набор, чтобы включить другие элементы кортежа. Если их несколько, мы удаляем их из списка, объединяем их и кортеж в один набор, затем добавляем этот набор в список.

res = []
for t in all_tuples:
    matched = []
    for s in res:
        if s.intersection(t):
            matched.append(s)
    if not matched:
        res.append(set(t))
    elif len(matched) == 1:
        matched[0].update(t)
    else:
        res = [subl for subl in res if subl not in matched]
        res.append(set.union(*matched, t))

print(res)
# [{242, 92}, {489, 436, 355, 403}, {515, 517, 775, 634, 859, 701}]
  • 0
    Этот ответ тоже хорош, но медленнее, чем ответ @WB. Спасибо
0

И просто причина, почему нет, здесь реализация с только списками и кортежами.

all_tuples=[(92, 242),(355, 403),(355, 436),(355, 489),(403, 436),(436, 489),(515, 517),(517, 859),(634, 775),(701, 859),(775, 859)]

curr_min, curr_max = all_tuples[0]
final = []
intermediate = [curr_min, curr_max]
for next_left, next_right in all_tuples[1:]:
    if curr_max >= next_left:
        intermediate.extend([next_left, next_right])
        curr_min, curr_max = min(curr_min, next_left), max(curr_max, next_right)
    else:
        final.append(set(intermediate))
        intermediate = []
        curr_min, curr_max = next_left, next_right
final.append(set(intermediate))

Ещё вопросы

Сообщество Overcoder
Наверх
Меню