用于在列表/集合中查找唯一元素的代码

时间:2018-03-05 20:08:10

标签: python python-3.x set venn-diagram set-theory

Shaded area required

根据Wolfram,上面的阴影区域应该代表:

 A XOR B XOR C XOR (A AND B AND C)

如何将其转换为python代码?代码必须与上面表达式中提供的集合操作密切相关,至少这是首选项。代码必须足够通用,以处理超过3个列表。

更新 好像Wolfram正在抛出一个错误的维恩图? 另外,我们真正想要的是

(A XOR B XOR C) - (A AND B AND C)

我无法在Wolfram中表示这一点。

2 个答案:

答案 0 :(得分:3)

Python支持集合(more about sets)。对于三个列表,它将是:

A = [1, 2, 3, 4]
B = [2, 3, 5, 6]
C = [3, 4, 5, 7]
As = set(A)
Bs = set(B)
Cs = set(C)

print((As ^ Bs ^ Cs) ^ (As & Bs & Cs))

对于列表清单(这是错误的 - 它所做的只是对所有集进行异或,对所有集进行AND运算而不是对这两个结果进行异或 - 正确的解决方案):

import functools

def do_xor(s1, s2):
    return s1 ^ s2

def do_and(s1, s2):
    return s1 & s2

def do_task(list_of_lists):
    list_of_sets = list(map(set, list_of_lists))
    xors = functools.reduce(do_xor, list_of_sets)
    ands = functools.reduce(do_and, list_of_sets)
    return xors ^ ands

A = [1, 2, 3, 4]
B = [2, 3, 5, 6]
C = [3, 4, 5, 7]
D=[A, B, C]
print(do_task(D))

正确的解决方案:

import functools 

def do_or(s1, s2):
    return s1 | s2

def do_task2(list_of_lists):
    list_of_sets = list(map(set, list_of_lists))
    list_of_intersects = [X & Y for X in list_of_sets for Y in list_of_sets if X is not Y]
    intersects = functools.reduce(do_or, list_of_intersects)
    ors = functools.reduce(do_or, list_of_sets)
    return ors - intersects

lol33 = [
    [1, 2], 
    [3, 2], 
    [3], 
    [3, 2, 4]
    ]

print(do_task2(lol33)) # {1, 4}

答案 1 :(得分:0)

您可以将操作& [intersection]和| [union]用于您的目的。来自@WPedrak的数据。

A = {1, 2, 3, 4}
B = {2, 3, 5, 6}
C = {3, 4, 5, 7}

lst = [A, B, C]

result = (A | B | C) - ((A & B) | (A & C) | (B & C) | (A & B & C))

# {1, 6, 7}

<强>解释

我们采用所有元素的并集并减去所有交叉点。有关一般情况,请参阅@WPedrak's solution