【问题标题】:Union of 2 sets does not contain all items2 组并集不包含所有项目
【发布时间】:2017-11-13 08:27:44
【问题描述】:

为什么我在下面的并集中改变了两个集合的顺序,会得到不同的结果?

set1 = {1, 2, 3}
set2 = {True, False}

print(set1 | set2)
# {False, 1, 2, 3}

print(set2 | set1)
#{False, True, 2, 3}

【问题讨论】:

    标签: python python-3.x set equivalence-classes


    【解决方案1】:

    为什么 union() 不包含所有项目

    1True 是等价的并且被认为是重复的。同样0False 也是等价的:

    >>> 1 == True
    True
    >>> 0 == False
    True
    

    使用哪个等效值

    当遇到多个等效值时,集合保持第一个可见:

    >>> {0, False}
    {0}
    >>> {False, 0}
    {False}
    

    使值不同的方法

    要让它们被视为不同,只需将它们存储在 (value, type) 对中:

    >>> set1 = {(1, int), (2, int), (3, int)}
    >>> set2 = {(True, bool), (False, bool)}
    >>> set1 | set2
    {(3, <class 'int'>), (1, <class 'int'>), (2, <class 'int'>),
     (True, <class 'bool'>), (False, <class 'bool'>)}
    >>> set1 & set2
    set()
    

    另一种使值不同的方法是将它们存储为字符串:

    >>> set1 = {'1', '2', '3'}
    >>> set2 = {'True', 'False'}
    >>> set1 | set2
    {'2', '3', 'False', 'True', '1'}
    >>> set1 & set2
    set()
    

    希望这能解开谜团并指明前进的方向:-)


    从 cmets 中获救:

    这是打破跨类型等价的标准技术(即0.0 == 0True == 1Decimal(8.5) == 8.5)。该技术用于 Python 2.7 的正则表达式模块以强制将 unicode 正则表达式与否则等效的 str 正则表达式。当 typed 参数为 true 时,该技术也用于 Python 3 中的 functools.lru_cache()。

    如果 OP 需要默认等价关系以外的东西,则需要定义一些新关系。根据用例,这可能是字符串的大小写不敏感、unicode 的规范化、视觉外观(看起来不同的东西被认为是不同的)、身份(没有两个不同的对象被认为是相等的)、值/类型对或其他一些定义等价关系的函数。鉴于 OP 的具体示例,他/她似乎期望按类型或视觉区别进行区分。

    【讨论】:

      【解决方案2】:

      在 Python 中,False0 被认为是等价的,True1 也是如此。因为True1 被认为是相同的值,所以只有其中一个可以同时出现在一个集合中。哪一个取决于它们添加到集合中的顺序。在第一行中,set1 用作第一个集合,因此我们在结果集中得到1。在第二组中,True 在第一组中,所以True 包含在结果中。

      【讨论】:

        【解决方案3】:

        如果您查看https://docs.python.org/3/library/stdtypes.html#boolean-values 第 4.12.10 节。布尔值:

        布尔值是两个常量对象False 和True。它们用于表示真值(尽管其他值也可以被认为是假或真)。在数字上下文中(例如,用作算术运算符的参数时),它们的行为分别类似于 整数 0 和 1

        【讨论】:

          【解决方案4】:

          比较运算符(==!=)是为布尔值 TrueFalse 定义的,以匹配 1 和 0。

          这就是为什么在集合并集中,当它检查True 是否已经在新集合中时,它会得到一个真实的答案:

          >>> True in {1}
          True
          >>> 1 in {True}
          True
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-03-29
            相关资源
            最近更新 更多