删除已存在于另一个元组中的集合中的元组对

时间:2017-03-06 13:37:47

标签: python duplicates set tuples

我有一套

例如:

(7, 8)

但是当一个元组对已经在另一个元组中时我想删除它。

例如: (2, 3, 7, 8)位于(1, 3)(1, 2, 3)位于(1, 6) (1, 6, 8)位于{(2, 3, 7, 8), (4, 6), (4, 8), (1, 2, 3), (1, 6, 8), (3, 5)}

所以这个集合变成了:

{{1}}

元组中元素的顺序并不重要,你应该始终保持最长的序列。

你是怎么做到的?

3 个答案:

答案 0 :(得分:2)

这不是一个非常有效的解决方案(O(n ^ 2);遍历集合两次)但我不确定我们能在这里做得更好。

my_set = {(2, 3, 7, 8), (1, 3), (4, 6), (4, 8), (1, 2, 3), (1, 6), (7, 8), (1, 6, 8), (3, 5)}

remove = set()
for i in my_set:
    for j in my_set:
        if i != j and all(f not in remove for f in (i, j)):
            if all(x in j for x in i):
                remove.add(i)

res = my_set - remove
print(res)  # {(2, 3, 7, 8), (4, 6), (4, 8), (1, 2, 3), (1, 6, 8), (3, 5)}

请注意,它将内部元组转换为集合并对其设置了一些限制(元组上没有重复元素)

答案 1 :(得分:1)

我们可以通过将元组转换为集合,然后将集合转换回元组来更有效地进行测试。我使用frozensets因为它们是不可变的,就像元组一样。

src = {
    (2, 3, 7, 8), (1, 3), (4, 6), (4, 8), (1, 2, 3), 
    (1, 6), (7, 8), (1, 6, 8), (3, 5)
}

temp = [frozenset(u) for u in src]
temp.sort(key=len, reverse=True)

dest = []
for t in temp:
    if not any(t <= u for u in dest):
        dest.append(t)

dest = {tuple(sorted(u)) for u in dest}
print(dest)

<强>输出

{(2, 3, 7, 8), (4, 6), (4, 8), (1, 2, 3), (1, 6, 8), (3, 5)}

我们首先将元组转换为集合并将它们存储在列表中,按长度对列表项进行排序,从最长到最短。然后,我们将每个列表项添加到dest列表中,前提是它不是现有项的子集。然后我们使用set comprehension将集合转换回有序元组。

答案 2 :(得分:1)

from pprint import pprint

S = {(2, 3, 7, 8), (1, 3), (4, 6), (4, 8), (1, 2, 3), (1, 6), (7, 8), (1, 6, 8), (3, 5)}

V = {frozenset(s) for s in S}

W = {x for x in V if not any(x <= y for y in V - {x})}

pprint(W)

输出

set([frozenset([4, 8]),
     frozenset([3, 5]),
     frozenset([2, 3, 7, 8]),
     frozenset([4, 6]),
     frozenset([1, 6, 8]),
     frozenset([1, 2, 3])])