2017-02-10 47 views
2

我的数据是一组frozenset的,例如,蟒发现集与共享元素

data = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]), frozenset([100,200]), frozenset([1,1000, 2000])]) 

和预期的结果是一组具有重复的元素frozenset的,即

result = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]), frozenset([1,1000, 2000])]) 

这里frozenset([100,200])被删除,因为它不会与其他frozensets共享任何元素。什么是有效的实现方式?

+0

你为什么在这里使用'frozenset's?他们的用例非常罕见我找到 –

+0

每个frozenset表示图中的一个环,然后我需要检查环匹配和环结果。因此我保留了一组戒指,然后每个戒指都必须进行冻结设置以达到散列目的。你对数据组织有其他建议吗? – nos

+0

啊,很好,那实际上听起来像一个有效的用例:) –

回答

2

你可以建立一个dict集合元素到它们被发现的次数的计数,然后删除其所有元素的计数为1的任何frozensetcollections.Counter对于这个将会很方便。

这具有以下优点:O(n)其中n是所有集合中元素的总数。

from collections import Counter 

data = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]), frozenset([100,200]), frozenset([1,1000, 2000])]) 
counts = Counter(elt for fs in data for elt in fs) 
result = {fs for fs in data if any(counts[elt] > 1 for elt in fs)} 

# {frozenset({1, 2, 3, 4}), frozenset({1000, 1, 2000}), frozenset({3, 4, 5, 6, 7, 8})} 
1

我愿意做一套理解有了这样的检查(对于每个项目,检查它是否具有与至少1个其他元件共同元素):

data = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]), frozenset([100,200]), frozenset([1,1000, 2000])]) 

new_data = {x for x in data if any(not x.isdisjoint(y) for y in data if y!=x)} 

print(new_data) 

结果:

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

可能会有更高效的解决方案,但至少disjoint部分是由有效的set例程处理

0

这是我的版本,它没有任何特别的优势,但是您可能会发现它更具可读性。

data = set([frozenset([1,2,3,4]), frozenset([3,4,5,6,7,8]), frozenset([100,200]), frozenset([1,1000, 2000])]) 
result = set() 

for item in data: 
    for element in item: 
     for other_item in data: 
      if item != other_item and item not in result: 
       if element in other_item: 
        result.add(item) 
        break 
>>>print(result) 
>>>{frozenset({1, 2, 3, 4}), frozenset({1000, 1, 2000}), frozenset({3, 4, 5, 6, 7, 8})}