"0 in [True,False]" returns True

Discussion in 'Python' started by Pierre Quentel, Dec 12, 2005.

  1. Hi all,

    In some program I was testing if a variable was a boolean, with this
    test : if v in [True,False]

    My script didn't work in some cases and I eventually found that for v =
    0 the test returned True

    So I changed my test for the obvious "if type(v) is bool", but I still
    find it confusing that "0 in [True,False]" returns True

    By the way, I searched in the documentation what "obj in list" meant and
    couldn't find a precise definition (does it test for equality or
    identity with one of the values in list ? equality, it seems) ; did I
    miss something ?

    Regards,
    Pierre
     
    Pierre Quentel, Dec 12, 2005
    #1
    1. Advertising

  2. Pierre Quentel wrote:

    > In some program I was testing if a variable was a boolean, with this
    > test : if v in [True,False]
    >
    > My script didn't work in some cases and I eventually found that for v =
    > 0 the test returned True
    >
    > So I changed my test for the obvious "if type(v) is bool", but I still
    > find it confusing that "0 in [True,False]" returns True
    >
    > By the way, I searched in the documentation what "obj in list" meant and
    > couldn't find a precise definition (does it test for equality or
    > identity with one of the values in list ? equality, it seems) ; did I
    > miss something ?


    >>> issubclass(bool, int)

    True
    >>> isinstance(False, int)

    True
    >>> False == 0

    True
    >>> int(False)

    0

    but seriously, unless you're writing an introspection tool, testing for
    bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    Python.

    </F>
     
    Fredrik Lundh, Dec 12, 2005
    #2
    1. Advertising

  3. On Mon, 2005-12-12 at 16:26, Pierre Quentel wrote:
    > Hi all,
    >
    > In some program I was testing if a variable was a boolean, with this
    > test : if v in [True,False]
    >
    > My script didn't work in some cases and I eventually found that for v =
    > 0 the test returned True
    >
    > So I changed my test for the obvious "if type(v) is bool", but I still
    > find it confusing that "0 in [True,False]" returns True
    >
    > By the way, I searched in the documentation what "obj in list" meant and
    > couldn't find a precise definition (does it test for equality or
    > identity with one of the values in list ? equality, it seems) ; did I
    > miss something ?


    Where/how did you search? http://docs.python.org/lib/typesseq.html
    states unambiguously that "x in s" returns "True if an item of s is
    equal to x, else False"

    HTH,

    Carsten.
     
    Carsten Haese, Dec 12, 2005
    #3
  4. Pierre Quentel wrote:
    > In some program I was testing if a variable was a boolean, with this
    > test : if v in [True,False]
    >
    > My script didn't work in some cases and I eventually found that for v =
    > 0 the test returned True


    This seems like a strange test. What is this code trying to do?

    If you're sure you have to do this, I would do either:

    if isinstance(v, bool):
    ...

    or

    if v is True or v is False:
    ...

    But it really seems like this code is trying to code some other language
    in Python...

    STeVe
     
    Steven Bethard, Dec 13, 2005
    #4
  5. Pierre Quentel

    David Wahler Guest

    Pierre Quentel wrote:
    > Hi all,
    >
    > In some program I was testing if a variable was a boolean, with this
    > test : if v in [True,False]
    >
    > My script didn't work in some cases and I eventually found that for v =
    > 0 the test returned True
    >
    > So I changed my test for the obvious "if type(v) is bool", but I still
    > find it confusing that "0 in [True,False]" returns True


    >From the docs: Python Library Reference, section 2.3.10.9:

    "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."

    I don't blame you for not knowing about this; it is rather unintuitive.

    -- David
     
    David Wahler, Dec 13, 2005
    #5
  6. Pierre Quentel

    Guest

    Fredrik Lundh wrote:
    > Pierre Quentel wrote:
    >
    > > In some program I was testing if a variable was a boolean, with this
    > > test : if v in [True,False]
    > >
    > > My script didn't work in some cases and I eventually found that for v =
    > > 0 the test returned True
    > >
    > > So I changed my test for the obvious "if type(v) is bool", but I still
    > > find it confusing that "0 in [True,False]" returns True
    > >
    > > By the way, I searched in the documentation what "obj in list" meant and
    > > couldn't find a precise definition (does it test for equality or
    > > identity with one of the values in list ? equality, it seems) ; did I
    > > miss something ?

    >
    > >>> issubclass(bool, int)

    > True
    > >>> isinstance(False, int)

    > True
    > >>> False == 0

    > True
    > >>> int(False)

    > 0
    >
    > but seriously, unless you're writing an introspection tool, testing for
    > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    > Python.
    >

    The OP's code(and his work around) doesn't look like he is testing for
    boolean but more like the data type of something. I thought there is
    some idiom in python which said something like "don't assume" ?
     
    , Dec 13, 2005
    #6
  7. wrote:

    > > but seriously, unless you're writing an introspection tool, testing for
    > > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    > > Python.
    > >

    > The OP's code(and his work around) doesn't look like he is testing for
    > boolean


    which of course explains why he wrote

    In some program I was testing if a variable was a boolean

    in the post I replied to...

    > but more like the data type of something. I thought there is some idiom
    > in python which said something like "don't assume" ?


    "think before you post" ?

    </F>
     
    Fredrik Lundh, Dec 13, 2005
    #7
  8. Pierre Quentel

    Guest

    Fredrik Lundh wrote:
    > wrote:
    >
    > > > but seriously, unless you're writing an introspection tool, testing for
    > > > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    > > > Python.
    > > >

    > > The OP's code(and his work around) doesn't look like he is testing for
    > > boolean

    >
    > which of course explains why he wrote
    >
    > In some program I was testing if a variable was a boolean
    >
    > in the post I replied to...
    >
    > > but more like the data type of something. I thought there is some idiom
    > > in python which said something like "don't assume" ?

    >
    > "think before you post" ?
    >

    Don't know what you mean.

    He seems to be testing "boolean type", not whether it is true or false.
     
    , Dec 13, 2005
    #8
  9. Op 2005-12-12, Fredrik Lundh schreef <>:
    > Pierre Quentel wrote:
    >
    >> In some program I was testing if a variable was a boolean, with this
    >> test : if v in [True,False]
    >>
    >> My script didn't work in some cases and I eventually found that for v =
    >> 0 the test returned True
    >>
    >> So I changed my test for the obvious "if type(v) is bool", but I still
    >> find it confusing that "0 in [True,False]" returns True
    >>
    >> By the way, I searched in the documentation what "obj in list" meant and
    >> couldn't find a precise definition (does it test for equality or
    >> identity with one of the values in list ? equality, it seems) ; did I
    >> miss something ?

    >
    >>>> issubclass(bool, int)

    > True
    >>>> isinstance(False, int)

    > True
    >>>> False == 0

    > True
    >>>> int(False)

    > 0
    >
    > but seriously, unless you're writing an introspection tool, testing for
    > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    > Python.


    That depends on the circumstances. I have code where a particular
    variable can be a boolean or an integer. I don't want that code
    to behave the same on 0 and False nor on any other number and
    True.

    --
    Antoon Pardon
     
    Antoon Pardon, Dec 13, 2005
    #9
  10. Pierre Quentel

    Guest

    Antoon Pardon wrote:
    > Op 2005-12-12, Fredrik Lundh schreef <>:
    > > Pierre Quentel wrote:
    > >
    > >> In some program I was testing if a variable was a boolean, with this
    > >> test : if v in [True,False]
    > >>
    > >> My script didn't work in some cases and I eventually found that for v =
    > >> 0 the test returned True
    > >>
    > >> So I changed my test for the obvious "if type(v) is bool", but I still
    > >> find it confusing that "0 in [True,False]" returns True
    > >>
    > >> By the way, I searched in the documentation what "obj in list" meant and
    > >> couldn't find a precise definition (does it test for equality or
    > >> identity with one of the values in list ? equality, it seems) ; did I
    > >> miss something ?

    > >
    > >>>> issubclass(bool, int)

    > > True
    > >>>> isinstance(False, int)

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

    > > True
    > >>>> int(False)

    > > 0
    > >
    > > but seriously, unless you're writing an introspection tool, testing for
    > > bool is pretty silly. just use "if v" or "if not v", and leave the rest to
    > > Python.

    >
    > That depends on the circumstances. I have code where a particular
    > variable can be a boolean or an integer. I don't want that code
    > to behave the same on 0 and False nor on any other number and
    > True.
    >

    Then your program/implementation/requirement is wrong because it
    doesn't fit in the use case of "if v:" or "if not v:", refactor ;-)
     
    , Dec 13, 2005
    #10
  11. Pierre Quentel

    Steve Holden Guest

    Pierre Quentel wrote:
    > Hi all,
    >
    > In some program I was testing if a variable was a boolean, with this
    > test : if v in [True,False]
    >
    > My script didn't work in some cases and I eventually found that for v =
    > 0 the test returned True
    >
    > So I changed my test for the obvious "if type(v) is bool", but I still
    > find it confusing that "0 in [True,False]" returns True
    >
    > By the way, I searched in the documentation what "obj in list" meant and
    > couldn't find a precise definition (does it test for equality or
    > identity with one of the values in list ? equality, it seems) ; did I
    > miss something ?
    >

    It actually uses the __contains__() method of the right-hand operand,
    and in the case of a list that will test for equality of the left-hand
    operand to one of the list elements. Since False == 0 that's why you see
    what you do.

    The really interesting question your post raises, though, is "Why do you
    feel it's necessary to test to see whether a variable is a Boolean?".

    regards
    Steve
    --
    Steve Holden +44 150 684 7255 +1 800 494 3119
    Holden Web LLC www.holdenweb.com
    PyCon TX 2006 www.python.org/pycon/
     
    Steve Holden, Dec 13, 2005
    #11
  12. Pierre Quentel

    Paul Rubin Guest

    Steve Holden <> writes:
    > The really interesting question your post raises, though, is "Why do
    > you feel it's necessary to test to see whether a variable is a
    > Boolean?".


    What's the point of having Booleans, if you can't tell them from integers?
     
    Paul Rubin, Dec 13, 2005
    #12
  13. Op 2005-12-13, Steve Holden schreef <>:
    > Pierre Quentel wrote:
    >> Hi all,
    >>
    >> In some program I was testing if a variable was a boolean, with this
    >> test : if v in [True,False]
    >>
    >> My script didn't work in some cases and I eventually found that for v =
    >> 0 the test returned True
    >>
    >> So I changed my test for the obvious "if type(v) is bool", but I still
    >> find it confusing that "0 in [True,False]" returns True
    >>
    >> By the way, I searched in the documentation what "obj in list" meant and
    >> couldn't find a precise definition (does it test for equality or
    >> identity with one of the values in list ? equality, it seems) ; did I
    >> miss something ?
    >>

    > It actually uses the __contains__() method of the right-hand operand,
    > and in the case of a list that will test for equality of the left-hand
    > operand to one of the list elements. Since False == 0 that's why you see
    > what you do.
    >
    > The really interesting question your post raises, though, is "Why do you
    > feel it's necessary to test to see whether a variable is a Boolean?".


    I can give you one example. I have written a tube class. A tube behaves
    like Queue but it has additional code so that it can be registed with
    gtk in the same way as file descriptor can be registered with
    io_add_watch. The way this is implemented is by registering an idle
    handler when the tube is not empty and removing it when the tube is
    empty. So I have a variable cb_src (for callback source) that can be
    a boolean or an integer. The possible values are

    False: Not registered by the user
    True: Registered by the user but no nternal idle callback registerd
    a number: gtk integer ID, from the registered idle callback handler.

    --
    Antoon Pardon
     
    Antoon Pardon, Dec 13, 2005
    #13
  14. Paul Rubin wrote:

    > Steve Holden <> writes:
    >> The really interesting question your post raises, though, is "Why do
    >> you feel it's necessary to test to see whether a variable is a
    >> Boolean?".

    >
    > What's the point of having Booleans, if you can't tell them from integers?


    Because

    return True

    is clearer than

    return 1

    if the purpose of the return value is to indicate a Boolean rather than
    an arbitrary integer.

    --
    Erik Max Francis && && http://www.alcyone.com/max/
    San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    The basis of optimism is sheer terror.
    -- Oscar Wilde
     
    Erik Max Francis, Dec 13, 2005
    #14
  15. Erik Max Francis wrote:

    > > What's the point of having Booleans, if you can't tell them from integers?

    >
    > Because
    >
    > return True
    >
    > is clearer than
    >
    > return 1
    >
    > if the purpose of the return value is to indicate a Boolean rather than
    > an arbitrary integer.


    the real reason booleans were added was that sillyness like

    True = 1 == 1
    False = not True

    and

    return 1 # true

    and

    class Boolean:

    def __init__(self, value = 0):
    self.value = operator.truth(value)

    def __cmp__(self, other):
    if isinstance(other, Boolean):
    other = other.value
    return cmp(self.value, other)

    def __repr__(self):
    if self.value:
    return "<Boolean True at %x>" % id(self)
    else:
    return "<Boolean False at %x>" % id(self)

    def __int__(self):
    return self.value

    def __nonzero__(self):
    return self.value

    True, False = Boolean(1), Boolean(0)

    were all too common in the wild.

    for the full story, see

    http://www.python.org/peps/pep-0285.html

    and, to briefly return to the original topic, note that

    "This PEP does *not* change the fact that almost all object types
    can be used as truth values. For example, when used in an if
    statement, an empty list is false and a non-empty one is true;
    this does not change and there is no plan to ever change this.

    The only thing that changes is the preferred values to represent
    truth values when returned or assigned explicitly. Previously,
    these preferred truth values were 0 and 1; the PEP changes the
    preferred values to False and True, and changes built-in
    operations to return these preferred values."

    in general, returning True and False is pythonic, explicitly testing for
    them is not.

    </F>
     
    Fredrik Lundh, Dec 13, 2005
    #15
  16. Pierre Quentel

    Steve Holden Guest

    Paul Rubin wrote:
    > Steve Holden <> writes:
    >
    >>The really interesting question your post raises, though, is "Why do
    >>you feel it's necessary to test to see whether a variable is a
    >>Boolean?".

    >
    >
    > What's the point of having Booleans, if you can't tell them from integers?


    Booleans are specifically defined as a subtype of int at the C level.
    One might also ask "what's the point of having floats if you can't tell
    them from integers":

    >>> 0.0 in [1,2,0,4]

    True
    >>>


    It just so happens that __contains__() uses an equality test (which it
    should) and equality tests perform certain coercions (which they
    arguably shouldn't, but in that case I wouldn't be the one doing the
    arguing).

    """
    The only thing that changes is the preferred values to represent
    truth values when returned or assigned explicitly. Previously,
    these preferred truth values were 0 and 1; the PEP changes the
    preferred values to False and True, and changes built-in
    operations to return these preferred values.
    """

    PEP 285.

    regards
    Steve
    --
    Steve Holden +44 150 684 7255 +1 800 494 3119
    Holden Web LLC www.holdenweb.com
    PyCon TX 2006 www.python.org/pycon/
     
    Steve Holden, Dec 13, 2005
    #16
  17. Pierre Quentel

    Robin Becker Guest

    Carsten Haese wrote:
    ........
    >
    > Where/how did you search? http://docs.python.org/lib/typesseq.html
    > states unambiguously that "x in s" returns "True if an item of s is
    > equal to x, else False"

    ......

    exactly and I see

    >>> 0==False

    True
    >>>


    so I guess nothing is wrong :)
    --
    Robin Becker
     
    Robin Becker, Dec 13, 2005
    #17
  18. Pierre Quentel

    Guest

    Erik Max Francis wrote:
    > Paul Rubin wrote:
    >
    > > Steve Holden <> writes:
    > >> The really interesting question your post raises, though, is "Why do
    > >> you feel it's necessary to test to see whether a variable is a
    > >> Boolean?".

    > >
    > > What's the point of having Booleans, if you can't tell them from integers?

    >
    > Because
    >
    > return True
    >
    > is clearer than
    >
    > return 1
    >
    > if the purpose of the return value is to indicate a Boolean rather than
    > an arbitrary integer.
    >

    True, but if that is the only reason, Two built-in value of
    True/False(0/1) serves the need which is what is now(well sort of). Why
    have seperate types and distinguish them ?

    >>>True == 1

    True
    >>>True is 1

    False
     
    , Dec 13, 2005
    #18
  19. Pierre Quentel

    Steve Holden Guest

    Antoon Pardon wrote:
    > Op 2005-12-13, Steve Holden schreef <>:
    >
    >>Pierre Quentel wrote:
    >>
    >>>Hi all,
    >>>
    >>>In some program I was testing if a variable was a boolean, with this
    >>>test : if v in [True,False]
    >>>
    >>>My script didn't work in some cases and I eventually found that for v =
    >>>0 the test returned True
    >>>
    >>>So I changed my test for the obvious "if type(v) is bool", but I still
    >>>find it confusing that "0 in [True,False]" returns True
    >>>
    >>>By the way, I searched in the documentation what "obj in list" meant and
    >>>couldn't find a precise definition (does it test for equality or
    >>>identity with one of the values in list ? equality, it seems) ; did I
    >>>miss something ?
    >>>

    >>
    >>It actually uses the __contains__() method of the right-hand operand,
    >>and in the case of a list that will test for equality of the left-hand
    >>operand to one of the list elements. Since False == 0 that's why you see
    >>what you do.
    >>
    >>The really interesting question your post raises, though, is "Why do you
    >>feel it's necessary to test to see whether a variable is a Boolean?".

    >
    >
    > I can give you one example. I have written a tube class. A tube behaves
    > like Queue but it has additional code so that it can be registed with
    > gtk in the same way as file descriptor can be registered with
    > io_add_watch. The way this is implemented is by registering an idle
    > handler when the tube is not empty and removing it when the tube is
    > empty. So I have a variable cb_src (for callback source) that can be
    > a boolean or an integer. The possible values are
    >
    > False: Not registered by the user
    > True: Registered by the user but no nternal idle callback registerd
    > a number: gtk integer ID, from the registered idle callback handler.
    >

    Well I guess you'd better hope that gtk never returns a zero or one, then.

    Note, though, that True and False are defined to be singleton instances,
    so it *is* permissible to say

    if i is False:

    >>> 0 is False

    False
    >>> 1 is True

    False
    >>>


    However I must say the coupling in that interface has a very definite
    code smell. Why not use two variables, a Boolean "registered" and an
    integer ID that is meaningless when registered is False?

    regards
    Steve
    --
    Steve Holden +44 150 684 7255 +1 800 494 3119
    Holden Web LLC www.holdenweb.com
    PyCon TX 2006 www.python.org/pycon/
     
    Steve Holden, Dec 13, 2005
    #19
  20. wrote:

    > True, but if that is the only reason, Two built-in value of
    > True/False(0/1) serves the need which is what is now(well sort of). Why
    > have seperate types and distinguish them ?


    Because of this:

    x = True
    y = 1 # but I mean it to represent true

    print x, y

    Besides, it's not the only reason, but it's a good one.

    --
    Erik Max Francis && && http://www.alcyone.com/max/
    San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
    Ipsa scientia potestas est. "Knowledge itself is power."
    -- a Latin proverb
     
    Erik Max Francis, Dec 13, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. vizlab
    Replies:
    3
    Views:
    4,213
    Michael Bar-Sinai
    Oct 17, 2007
  2. ++imanshu
    Replies:
    7
    Views:
    477
    ++imanshu
    Aug 23, 2008
  3. bdb112
    Replies:
    45
    Views:
    1,348
    jazbees
    Apr 29, 2009
  4. Trans
    Replies:
    2
    Views:
    228
    Trans
    Nov 6, 2005
  5. Russ Cordner

    ? true : false returns nil?

    Russ Cordner, Apr 15, 2009, in forum: Ruby
    Replies:
    4
    Views:
    119
    Darryl L. Pierce
    Apr 16, 2009
Loading...

Share This Page