如何在python中添加多个集合,但仅限于项目是唯一的

时间:2018-02-07 23:03:11

标签: python

我需要添加一个未确定数量的列表(集),但我只想添加成员(如果它们是唯一的)

(1,2,3) (3,4,5) (-4,7,8,9-) (5,3,9)

需要给出:(1,2,7,8)

6 个答案:

答案 0 :(得分:7)

from collections import Counter
from itertools import chain

lst = [(1,2,3), (3,4,5), (4,7,8,9), (5,3,9)]

[k for k, v in Counter(chain.from_iterable(lst)).items() if v==1]

# [1, 2, 7, 8]

为了最低成本,您还可以返回计数为2,3等的值

答案 1 :(得分:1)

虽然Counter是更好的解决方案,但这是另一种方法:

import functools as ft


def get_disjoints(iterables):
    """Return a list of disjoint elements."""
    def local_symdiff(a, b):
        """Return a symmetric difference of all observations."""
        a, b = set(a), set(b)
        intersections.update(a & b)
        return {x for x in a | b if x not in intersections}

    intersections = set()
    return ft.reduce(local_symdiff, iterables)


iterables = [(1,2,3), (3,4,5), (4,7,8,9), (5,3,9)]
get_disjoints(iterables)
# {1, 2, 7, 8}

将所有观察到的交叉点合并并过滤成对的迭代(通过functools.reduced)。

答案 2 :(得分:0)

试试这个:

def build_list(listnums):
      nummap = {}
      for n in listnums:
          for num in n: 
               if not num in nummap:
                   nummap[num] = True
               else:
                   nummap.pop(num, None)
      return list(nummap.keys())

答案 3 :(得分:0)

以下是更好的 *解决方案,仅使用设置操作和reduce()

all_sets = [{1,2,3}, {3,4,5}, {4,7,8,9}, {5,3,9}]
combined = reduce(
    lambda a, b: a.union(b),
    [
        s - reduce(
            lambda x, y: x.union(y), 
            [other for j, other in enumerate(all_sets) if j!=i]
        ) for i, s in enumerate(all_sets)
    ]
)
print(combined)
#set([8, 1, 2, 7])

浏览all_sets中的每个集合,并使用集合差异运算符(-)获取所有其他集合中的不同元素。然后我们使用set union()函数来减少此运算符的结果,以组合所有集合。

为了说明发生了什么,这里是内部列表理解的输出:

# this gets the elements in each set that are not in any of the others
inner = [
    s - reduce(
        lambda x, y: x.union(y), 
        [other for j, other in enumerate(all_sets) if j!=i]
    ) for i, s in enumerate(all_sets)
]
print(inner)
# [set([1, 2]), set([]), set([8, 7]), set([])]

*比我原来的解决方案更好。

原始解决方案

这是使用列表推导而不计算出现次数的解决方案。

all_sets = [{1,2,3}, {3,4,5}, {4,7,8,9}, {5,3,9}]
combined = [x for i, a in enumerate(all_sets) for x in a 
            if all(x not in b for j, b in enumerate(all_sets) if i!=j)]
print combined
#[1, 2, 7, 8]

迭代每个列表中的每个值,只有在任何其他列表中不存在时才将其添加到组合列表中。我们在所有列表中使用enumerate两次,以便我们可以跟踪“其他”列表的内容。

答案 4 :(得分:0)

def findSingles(t):
    l = [n for t in tuples for n in t]
    return tuple([i for i in l if l.count(i) == 1])

tuples = ((1,2,3), (3,4,5), (4,7,8,9), (5,3,9))

print(findSingles(tuples))    
# (1, 2, 7, 8)

答案 5 :(得分:-1)

你可以将元组扁平化,然后作为一组进行种姓:

s = [(1,2,3), (3,4,5), (4,7,8,9), (5,3,9)]
full_set = [i for b in s for i in b]
final_s = tuple(i for i in full_set if full_set.count(i) == 1)

输出:

(1, 2, 7, 8)