2 套并集不包含所有项目

Union of 2 sets does not contain all items

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

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

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

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

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

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

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

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

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

Boolean values are the two constant objects False and True. They are used to represent truth values (although other values can also be considered false or true). In numeric contexts (for example when used as the argument to an arithmetic operator), they behave like the integers 0 and 1, respectively.

为什么 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()

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


从评论中拯救出来:

这是打破跨类型等价的标准技术(即 0.0 == 0True == 1Decimal(8.5) == 8.5)。该技术在 Python 2.7 中使用正则表达式模块强制 unicode 正则表达式被缓存,与其他等效的 str 正则表达式不同。当类型参数为真时,该技术也用于 Python 3 for functools.lru_cache()。

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