найти симметричные пары, используя хэш-таблицу (словарь) в Python - PullRequest
0 голосов
/ 02 июня 2019

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

L=[(1,3), (2,6), (3,5), (4,7), (5,3), (6,2), (3,4),(4,3)]

, я хочу получить как [(2,6), (3,5), (3,4)], находя симметричные пары.

это мой полный код,

L=[(1,3), (2,6), (3,5), (4,7), (5,3), (6,2), (3,4),(4,3)]

def find_symmetric_pairs(L):
    temp = {}
    temp_list = []
    for i in L:
        key, value = i
        for j in L:
            key_j, value_j = j
            if key == value_j and value == key_j:
                temp_list.append(tuple((key,value)))
    return temp_list

а также я пытаюсь реализовать эту функцию с помощью хэш-таблицы python, как я могу использовать хеш-таблицу? Вывод выглядит так

[(2, 6), (3, 5), (5, 3), (6, 2), (3, 4), (4, 3)] но я хочу показать вывод, как выше, что я впервые сказал вам ... [(2,6), (3,5), (3,4)]

Ответы [ 3 ]

2 голосов
/ 02 июня 2019

В Python нет хеш-таблиц как таковых, но вы можете использовать наборы. Следующее объединяет исходный набор кортежей set(L) с набором обратных кортежей {(y, x) for x, y in L}. Позже он сохраняет только пары с меньшим первым элементом:

pairs = set(L) & {(y, x) for x, y in L}
{(x,y) for x,y in pairs if x < y}
#{(2, 6), (3, 4), (3, 5)}
2 голосов
/ 02 июня 2019

Вам просто нужно добавить проверку, чтобы увидеть, добавлена ​​ли уже симметричная пара к вашему результату,

L=[(1,3), (2,6), (3,5), (4,7), (5,3), (6,2), (3,4),(4,3)]

res = set()

#Convert the list to a set
L = set(L)
# Iterate through the set
for t in L:
    # If the a tuple is present , and the reversed tuple is not in the result set already
    if (t[1], t[0]) in L and (t[1], t[0]) not in res:
        # Add it to result set
        res.add(t)

print(res)

Вывод будет

{(2, 6), (4, 3), (3, 5)}

Другой подходпереупорядочить кортежи так, чтобы первый элемент был больше второго, и считать кортежи с помощью collections.Counter.Элементами с числом 2 будут симметричные пары

from collections import Counter

L=[(1,3), (2,6), (3,5), (4,7), (5,3), (6,2), (3,4),(4,3)]

#reorder tuple so that first element is bigger then second
L = [(t[1], t[0]) if t[0] < t[1] else t for t in L]

#Make a counter 
c = Counter(L)

#Count elements with count 2
res = [key for key, value in c.items() if value == 2]
print(res)

Выходные данные будут

[(6, 2), (5, 3), (4, 3)]
1 голос
/ 02 июня 2019

Вы можете использовать набор, если хотите игнорировать порядок.В частности, frozenset позволит вам хешировать и, следовательно, использовать Counter:

from collections import Counter
L_set_counter = Counter(map(frozenset, set(L)))

Теперь L_set_counter содержит:

Counter({frozenset({2, 6}): 2, frozenset({3, 5}): 2, frozenset({3, 4}): 2, frozenset({1, 3}): 1, frozenset({4, 7}): 1})

И найдите дубликаты (v==2, чтобы сделать его более конкретным, это более обобщенно):

dups = {k for k, v in L_set_counter.items() if v > 1}

А теперь dups содержит:

{frozenset({3, 4}), frozenset({3, 5}), frozenset({2, 6})}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...