为什么当我在下面的并集中更改两组的顺序时,会得到不同的结果?
set1 = {1, 2, 3}
set2 = {True, False}
print(set1 | set2)
# {False, 1, 2, 3}
print(set2 | set1)
#{False, True, 2, 3}
为什么当我在下面的并集中更改两组的顺序时,会得到不同的结果?
set1 = {1, 2, 3}
set2 = {True, False}
print(set1 | set2)
# {False, 1, 2, 3}
print(set2 | set1)
#{False, True, 2, 3}
1
和是等价的True
并且被认为是重复的。同样,0
andFalse
也是等价的:
>>> 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 == 0
,True == 1
和Decimal(8.5) == 8.5)
. 该技术在 Python 2.7 的正则表达式模块中使用,以强制将 unicode 正则表达式与其他等价的 str 正则表达式区分开来缓存。该技术也用于 Python 3 用于 functools.lru_cache() 当 typed 参数为真时。
如果 OP 需要默认等价关系以外的东西,则需要定义一些新关系。根据用例,这可能是字符串的大小写不敏感、unicode 的规范化、视觉外观(看起来不同的东西被认为是不同的)、身份(没有两个不同的对象被认为是相等的)、值/类型对或其他一些定义等价关系的函数。鉴于 OP 的具体示例,他/她似乎期望按类型或视觉区别进行区分。
在 Python 中,False
和0
被认为是等价的,True
和1
. 因为True
和1
被认为是相同的值,所以只有其中一个可以同时出现在一个集合中。哪一个取决于它们被添加到集合中的顺序。在第一行中,set1
被用作第一个集合,因此我们得到1
了结果集合。在第二组True
中,在第一组中,因此True
包含在结果中。
如果您查看https://docs.python.org/3/library/stdtypes.html#boolean-values部分 4.12.10。布尔值:
布尔值是两个常量对象False 和 True。它们用于表示真值(尽管其他值也可以被认为是假或真)。在数字上下文中(例如,当用作算术运算符的参数时),它们的行为分别类似于整数 0 和 1。
比较运算符 ( ==
, !=
) 是为布尔值定义的True
,False
用于匹配 1 和 0。
这就是为什么在集合并集中,当它检查是否True
已经在新集合中时,它会得到一个真实的答案:
>>> True in {1}
True
>>> 1 in {True}
True