【问题标题】:Code to find unique elements among lists / sets在列表/集合中查找唯一元素的代码
【发布时间】:2018-03-05 20:08:10
【问题描述】:

以上阴影区域,根据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 中表示这一点。

【问题讨论】:

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


    【解决方案1】:

    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))
    

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

    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}
    

    【讨论】:

    • 但是我有什么n 列表?
    • 如果lol1 = [ [1, 2], [3, 2] ],则do_task(lol1) 返回{1, 2, 3}。怎么会?
    • 我很好奇为什么这不起作用。使用它来进一步探测问题可能出在哪里...repl.it/@kgashok/MotionlessUnderstatedLinuxpc
    • 维恩图只是绘制集合之间关系的方法,而不是计算唯一元素的方法,所以它不会“出错”。异或和与所有集合(以问题中提到的方式)作为归档它的方法是错误的。
    • 谢谢,你也可以把do_or写成lambda函数:intersects = functools.reduce(lambda s1,s2: s1|s2, i)
    【解决方案2】:

    您可以使用操作 & [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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 2020-04-12
      • 1970-01-01
      • 2016-01-12
      • 2010-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多