簡體   English   中英

組合列表中的集合

[英]combining sets within a list

嗨,我正在嘗試執行以下操作,但是有點卡住了。 假設我有一組清單:

A = [set([1,2]), set([3,4]), set([1,6]), set([1,5])]

我想創建一個新列表,如下所示:

B = [ set([1,2,5,6]), set([3,4]) ]

即創建一個集合列表,如果集合重疊,則將它們合並在一起。 這可能很簡單,但是今天早上我不太明白。

這也有效並且很短:

import itertools

groups = [{'1', '2'}, {'3', '2'}, {'2', '4'}, {'5', '6'}, {'7', '8'}, {'7','9'}]

while True:
    for s1, s2 in itertools.combinations(groups, 2):
        if s1.intersection(s2):
            break
    else:
        break
    groups.remove(s1)
    groups.remove(s2)
    groups.append(s1.union(s2))

groups

這給出以下輸出:

[{'5', '6'}, {'1', '2', '3', '4'}, {'7', '8', '9'}]

while True確實對我來說有點危險,但有人有什么想法嗎?

怎么樣:

from collections import defaultdict

def sortOverlap(listOfTuples):

    # The locations of the values
    locations = defaultdict(lambda: [])

    # 'Sorted' list to return
    sortedList = []

    # For each tuple in the original list
    for i, a in enumerate(listOfTuples):

        for k, element in enumerate(a):

            locations[element].append(i)

    # Now construct the sorted list
    coveredElements = set()
    for element, tupleIndices in locations.iteritems():

        # If we've seen this element already then skip it
        if element in coveredElements:
            continue

        # Combine the lists
        temp = []
        for index in tupleIndices:

            temp += listOfTuples[index]

        # Add to the list of sorted tuples
        sortedList.append(list(set(temp)))

        # Record that we've covered this element
        for element in sortedList[-1]:
            coveredElements.add(element)

    return sortedList

# Run the example (with tuples)
print sortOverlap([(1,2), (3,4), (1,5), (1,6)])

# Run the example (with sets)
print sortOverlap([set([1,2]), set([3,4]), set([1,5]), set([1,6])])

您可以在for循環中使用intersection()和union():

A = [set([1,2]), set([3,4]), set([1,6]), set([1,5])]

intersecting = []

for someSet in A:
    for anotherSet in A:
        if someSet.intersection(anotherSet) and someSet != anotherSet:
            intersecting.append(someSet.union(anotherSet))
            A.pop(A.index(anotherSet))

A.pop(A.index(someSet))

finalSet = set([])
for someSet in intersecting:
    finalSet = finalSet.union(someSet)

A.append(finalSet)

print A

輸出: [set([3, 4]), set([1, 2, 5, 6])]

一個更直接的解決方案,

def overlaps(sets):
    overlapping = []
    for a in sets:
        match = False
        for b in overlapping:
            if a.intersection(b):
                b.update(a)
                match = True
                break
        if not match:
            overlapping.append(a)
    return overlapping

例子

>>> overlaps([set([1,2]), set([1,3]), set([1,6]), set([3,5])])
[{1, 2, 3, 5, 6}]
>>> overlaps([set([1,2]), set([3,4]), set([1,6]), set([1,5])])
[{1, 2, 5, 6}, {3, 4}]
for set_ in A:
    new_set = set(set_)
    for other_set in A:
        if other_set == new_set:
            continue
        for item in other_set:
            if item in set_:
                new_set = new_set.union(other_set)
                break
    if new_set not in B:
        B.append(new_set)

輸入輸出:

A = [set([1,2]), set([3,4]), set([2,3]) ]
B = [set([1, 2, 3]), set([2, 3, 4]), set([1, 2, 3, 4])]

A = [set([1,2]), set([3,4]), set([1,6]), set([1,5])]
B = [set([1, 2, 5, 6]), set([3, 4])]

A = [set([1,2]), set([1,3]), set([1,6]), set([3,5])]
B = [set([1, 2, 3, 6]), set([1, 2, 3, 5, 6]), set([1, 3, 5])]

此功能將完成工作,而無需觸摸輸入:

from copy import deepcopy


def remove_overlapped(input_list):
    input = deepcopy(input_list)
    output = []
    index = 1

    while input:
        head = input[0]
        try:
            next_item = input[index]
        except IndexError:
            output.append(head)
            input.remove(head)
            index = 1
            continue
        if head & next_item:
            head.update(next_item)
            input.remove(next_item)
            index = 1
        else:
            index += 1
    return output

這是執行您想要的功能。 可能不是最Python的,但能完成工作,最有可能改進很多。

from sets import Set

A = [set([1,2]), set([3,4]), set([2,3]) ]

merges = any( a&b for a in A for b in A if a!=b)
while(merges):
    B = [A[0]]
    for a in A[1:] :
        merged = False
        for i,b in enumerate(B):
            if  a&b :
                B[i]=b | a
                merged =True
                break

        if not merged:         
            B.append(a)
    A = B
    merges = any( a&b for a in A for b in A if a!=b)

print B  

發生了以下情況,我們循環了A中的所有集合(除了第一個,因為我們已經將其添加到了B中。我們檢查與B中所有集合的相交,如果相交結果不是False(又稱空集合) ),我們在集合上執行並集並開始下一個迭代,關於集合操作,請檢查以下頁面: https : //docs.python.org/2/library/sets.html&是交集運算符|是並集運算符

您可能可以使用any()等使用更多pythonic,但是wuold需要更多處理,因此我避免了

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM