简体   繁体   English

2套联盟不包含所有物品

[英]Union of 2 sets does not contain all items

How come when I change the order of the two sets in the unions below, I get different results? 为什么当我改变下面工会中两套的顺序时,我会得到不同的结果?

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

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

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

Why the union() doesn't contain all items 为什么union()不包含所有项目

The 1 and True are equivalent and considered to be duplicates. 1True是等价的,被认为是重复的。 Likewise the 0 and False are equivalent as well: 同样, 0False也是等价的:

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

Which equivalent value is used 使用哪个等效值

When multiple equivalent values are encountered, sets keep the first one seen: 遇到多个等效值时,set会保持第一个看到的值:

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

Ways to make the values be distinct 如何使价值观与众不同

To get them to be treated as distinct, just store them in a (value, type) pair: 要将它们视为不同,只需将它们存储在(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()

Another way to make the values distinct is to store them as strings: 使值不同的另一种方法是将它们存储为字符串:

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

Hope this clears up the mystery and shows the way forward :-) 希望这能揭开神秘面纱并展示前进的方向:-)


Rescued from the comments: 从评论中获救:

This is the standard technique for breaking cross-type equivalence (ie 0.0 == 0 , True == 1 , and Decimal(8.5) == 8.5) . 这是打破交叉类型等价的标准技术(即0.0 == 0True == 1Decimal(8.5) == 8.5) The technique is used in Python 2.7's regular expression module to force unicode regexes to be cached distinctly from otherwise equivalent str regexes. 该技术在Python 2.7的正则表达式模块中使用,以强制unicode正则表达式与其他等效的str正则表达式明显缓存。 The technique is also used in Python 3 for functools.lru_cache() when the typed parameter is true. 当typed参数为true时,该技术也在Python 3中用于functools.lru_cache()。

If the OP needs something other than the default equivalence relation, then some new relation needs to be defined. 如果OP需要除默认等价关系之外的其他东西,则需要定义一些新的关系。 Depending the use case, that could be case-insensitivity for strings, normalization for unicode, visual appearance (things that look different are considered different), identity (no two distinct objects are considered equal), a value/type pair, or some other function that defines an equivalence relation. 根据用例,可能是字符串不区分大小写,unicode规范化,视觉外观(看起来不同的东西被认为是不同的),标识(没有两个不同的对象被认为是相同的),值/类型对或其他一些定义等价关系的函数。 Given the OPs specific example, it would seem that he/she expected either distinction by type or visual distinction. 鉴于OP的具体示例,他/她似乎期望按类型或视觉区别进行区分。

In Python, False and 0 are considered equivalent, as are True and 1 . 在Python中, False0被认为是等价的, True1 Because True and 1 are considered the same value, only one of them can be present in a set a the same time. 因为True1被认为是相同的值,所以它们中只有一个可以同时出现在一个集合中。 Which one depends on the order they are added to the set in. In the first line, set1 is used as the first set, so we get 1 in the resulting set. 哪一个取决于它们被添加到集合中的顺序。在第一行中, set1用作第一个集合,因此我们在结果集合中得到1 In the second set, True is in the first set, so True is included in the result. 在第二组中, True在第一组中,因此True包含在结果中。

If you look at https://docs.python.org/3/library/stdtypes.html#boolean-values section 4.12.10. 如果你看一下https://docs.python.org/3/library/stdtypes.html#boolean-values第4.12.10节。 Boolean Values: 布尔值:

Boolean values are the two constant objects False and True . 布尔值是两个常量对象False和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. 在数字上下文中(例如,当用作算术运算符的参数时),它们的行为分别与整数0和1相似。

The comparison operator ( == , != ) is defined for boolean True and False to match 1 and 0. 比较运算符( ==!= )定义为布尔值TrueFalse以匹配1和0。

That's why, in the set union, when it checks whether True is in the new set already, it gets a truthy answer: 这就是为什么,在集合联盟中,当它检查True是否已经在新集合中时,它会得到一个真正的答案:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM