我怎么能在Python的集合中添加布尔值False而不是True?

时间:2018-07-24 19:01:25

标签: python set

我刚刚开始研究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}

3 个答案:

答案 0 :(得分:34)

因为使用Python 1 == True(和hash(1) == hash(True)),您的集合中已经有1个。

想象一下这个例子:

example1 = {0, False, None}
example2 = {1, True}

print(example1)
print(example2)

将输出:

{0, None}
{1}

第一个集合具有0None,因为0 == False0 != None。使用第二组1 == True时,True不会添加到该组中。

答案 1 :(得分:15)

如果set中已经包含01的布尔值丢失,则是因为以下行为...

>>> 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中不能保证此行为 ,原因很简单,TrueFalse不是保留关键字(此更改为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,1True以及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将不在集合中。