我刚刚开始研究Python中的设置数据类型。由于某种原因,每当我将布尔值True添加到集合中时,它都不会出现。但是,如果我将False添加到集合中,它将成为集合的元素。当我查询这个问题时,我感到震惊。
example1 = {1, 2, 7, False}
example2 = {7, 2, 4, 1, True}
print(example1)
print(example2)
输出为:
{False, 1, 2, 7}
{1, 2, 4, 7}
答案 0 :(得分:34)
因为使用Python 1 == True
(和hash(1) == hash(True)
),您的集合中已经有1个。
想象一下这个例子:
example1 = {0, False, None}
example2 = {1, True}
print(example1)
print(example2)
将输出:
{0, None}
{1}
第一个集合具有0
和None
,因为0 == False
但0 != None
。使用第二组1 == True
时,True
不会添加到该组中。
答案 1 :(得分:15)
如果set
中已经包含0
或1
的布尔值丢失,则是因为以下行为...
>>> hash(1) == hash(True)
True
>>> hash(0) == hash(False)
True
>>> 1 == True
>>> True
>>> 0 == False
>>> True
... is guaranteed in Python 3.x。
这意味着您不能同时拥有两个:
>>> set([True, 1])
{True}
>>> set([False, 0])
{False}
相等的哈希值与相等的对象一样重要,因为“相等”的对象可以产生不同的哈希值,反之亦然:
class Foo:
def __init__(self, x): self.x = x
def __hash__(self): return 1
def __eq__(self, other): return self.x == other.x
class Bar:
def __init__(self, x): self.x = x
def __hash__(self): return 2
def __eq__(self, other): return self.x == other.x
>>> x = Foo(3)
>>> y = Bar(3)
>>> x == y
True
>>> hash(x) == hash(y)
False
>>> set([x, y])
{<__main__.Bar at 0x56ed278>, <__main__.Foo at 0x5707390>}
如果这些项不相等,您还可以使用set
包含具有相同哈希值的项:
>>> hash('a')
-904409032991049157
>>> hash(-904409032991049157)
-904409032991049157
>>> hash('a') == hash(-904409032991049157)
True
>>> set(['a', -904409032991049157])
{-904409032991049157, 'a'}
在Python 2.x中不能保证此行为 ,原因很简单,True
和False
不是保留关键字(此更改为introduced in 3.x )。您可以重新分配它们(尽管最好不要分配),因此没有理由在Python 2.x中必须保持相同的行为:
>>> True = 5
>>> hash(True) == hash(1)
False
>>> set([1, True])
set([1, 5])
但是不要让True
替换为5
的事实使您感到沮丧!我们可以滥用类的表示形式,使其看起来好像True
确实在集合中:
class Foo(object):
def __repr__(self):
return('True')
>>> True = Foo()
>>> set([1, True])
set([1, True])
很显然,最后几对代码段是不好的做法,仅用于演示。主要结论是,具有相同散列的相等对象不能包含在相同的set
中,并且在Python 3.x,1
和True
以及0
和{ {1}},将始终具有相同的哈希值,并且将始终相等。
答案 2 :(得分:1)
False和True分别等于0和1。它们是不同的实体,但是两个相等的值不能同时在集合中。这显然是不希望有的行为,但尚不清楚它是否可以解决,是否仍然允许将其乘以布尔值以保证已记录。
IPython 6.2.1 -- An enhanced Interactive Python.
1 is True
Out[1]: False
{1,True}
Out[2]: {1}
{0,False}
Out[3]: {0}
{False, 0}
Out[4]: {False}
{True, 1}
Out[5]: {True}
请注意,根据将它们放入集合的顺序,如果集合中已经存在True,则1将不在集合中;如果集合中已经存在1,则True将不在集合中。