"0 in [True,False]" returns True

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Pierre Quentel

    "0 in [True,False]" returns True

    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
  • Fredrik Lundh

    #2
    Re: "0 in [True,False]" returns True

    Pierre Quentel wrote:
    [color=blue]
    > 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 ?[/color]
    [color=blue][color=green][color=darkred]
    >>> issubclass(bool , int)[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> isinstance(Fals e, int)[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> False == 0[/color][/color][/color]
    True[color=blue][color=green][color=darkred]
    >>> int(False)[/color][/color][/color]
    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>



    Comment

    • Carsten Haese

      #3
      Re: &quot;0 in [True,False]&quot; returns True

      On Mon, 2005-12-12 at 16:26, Pierre Quentel wrote:[color=blue]
      > 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 ?[/color]

      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.


      Comment

      • Steven Bethard

        #4
        Re: &quot;0 in [True,False]&quot; returns True

        Pierre Quentel wrote:[color=blue]
        > 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[/color]

        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

        Comment

        • Fredrik Lundh

          #5
          Re: &quot;0 in [True,False]&quot; returns True

          bonono@gmail.co m wrote:
          [color=blue][color=green]
          > > 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.
          > >[/color]
          > The OP's code(and his work around) doesn't look like he is testing for
          > boolean[/color]

          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...
          [color=blue]
          > but more like the data type of something. I thought there is some idiom
          > in python which said something like "don't assume" ?[/color]

          "think before you post" ?

          </F>



          Comment

          • bonono@gmail.com

            #6
            Re: &quot;0 in [True,False]&quot; returns True


            Fredrik Lundh wrote:[color=blue]
            > bonono@gmail.co m wrote:
            >[color=green][color=darkred]
            > > > 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.
            > > >[/color]
            > > The OP's code(and his work around) doesn't look like he is testing for
            > > boolean[/color]
            >
            > 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...
            >[color=green]
            > > but more like the data type of something. I thought there is some idiom
            > > in python which said something like "don't assume" ?[/color]
            >
            > "think before you post" ?
            >[/color]
            Don't know what you mean.

            He seems to be testing "boolean type", not whether it is true or false.

            Comment

            • Antoon Pardon

              #7
              Re: &quot;0 in [True,False]&quot; returns True

              Op 2005-12-12, Fredrik Lundh schreef <fredrik@python ware.com>:[color=blue]
              > Pierre Quentel wrote:
              >[color=green]
              >> 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 ?[/color]
              >[color=green][color=darkred]
              >>>> issubclass(bool , int)[/color][/color]
              > True[color=green][color=darkred]
              >>>> isinstance(Fals e, int)[/color][/color]
              > True[color=green][color=darkred]
              >>>> False == 0[/color][/color]
              > True[color=green][color=darkred]
              >>>> int(False)[/color][/color]
              > 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.[/color]

              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

              Comment

              • bonono@gmail.com

                #8
                Re: &quot;0 in [True,False]&quot; returns True


                Antoon Pardon wrote:[color=blue]
                > Op 2005-12-12, Fredrik Lundh schreef <fredrik@python ware.com>:[color=green]
                > > Pierre Quentel wrote:
                > >[color=darkred]
                > >> 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 ?[/color]
                > >[color=darkred]
                > >>>> issubclass(bool , int)[/color]
                > > True[color=darkred]
                > >>>> isinstance(Fals e, int)[/color]
                > > True[color=darkred]
                > >>>> False == 0[/color]
                > > True[color=darkred]
                > >>>> int(False)[/color]
                > > 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.[/color]
                >
                > 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.
                >[/color]
                Then your program/implementation/requirement is wrong because it
                doesn't fit in the use case of "if v:" or "if not v:", refactor ;-)

                Comment

                • Steve Holden

                  #9
                  Re: &quot;0 in [True,False]&quot; returns True

                  Pierre Quentel wrote:[color=blue]
                  > 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 ?
                  >[/color]
                  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/

                  Comment

                  • Paul Rubin

                    #10
                    Re: &quot;0 in [True,False]&quot; returns True

                    Steve Holden <steve@holdenwe b.com> writes:[color=blue]
                    > 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?".[/color]

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

                    Comment

                    • Antoon Pardon

                      #11
                      Re: &quot;0 in [True,False]&quot; returns True

                      Op 2005-12-13, Steve Holden schreef <steve@holdenwe b.com>:[color=blue]
                      > Pierre Quentel wrote:[color=green]
                      >> 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 ?
                      >>[/color]
                      > 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?".[/color]

                      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

                      Comment

                      • Erik Max Francis

                        #12
                        Re: &quot;0 in [True,False]&quot; returns True

                        Paul Rubin wrote:
                        [color=blue]
                        > Steve Holden <steve@holdenwe b.com> writes:[color=green]
                        >> 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?".[/color]
                        >
                        > What's the point of having Booleans, if you can't tell them from integers?[/color]

                        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 && max@alcyone.com && 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

                        Comment

                        • Steve Holden

                          #13
                          Re: &quot;0 in [True,False]&quot; returns True

                          Paul Rubin wrote:[color=blue]
                          > Steve Holden <steve@holdenwe b.com> writes:
                          >[color=green]
                          >>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?".[/color]
                          >
                          >
                          > What's the point of having Booleans, if you can't tell them from integers?[/color]

                          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":
                          [color=blue][color=green][color=darkred]
                          >>> 0.0 in [1,2,0,4][/color][/color][/color]
                          True[color=blue][color=green][color=darkred]
                          >>>[/color][/color][/color]

                          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/

                          Comment

                          • Fredrik Lundh

                            #14
                            Re: &quot;0 in [True,False]&quot; returns True

                            Erik Max Francis wrote:
                            [color=blue][color=green]
                            > > What's the point of having Booleans, if you can't tell them from integers?[/color]
                            >
                            > 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.[/color]

                            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(othe r, 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__(sel f):
                            return self.value

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

                            were all too common in the wild.

                            for the full story, see

                            This PEP proposes the introduction of a new built-in type, bool, with two constants, False and True. The bool type would be a straightforward subtype (in C) of the int type, and the values False and True would behave like 0 and 1 in most respects (for ...


                            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>



                            Comment

                            • Robin Becker

                              #15
                              Re: &quot;0 in [True,False]&quot; returns True

                              Carsten Haese wrote:
                              ........[color=blue]
                              >
                              > 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"[/color]
                              ......

                              exactly and I see
                              [color=blue][color=green][color=darkred]
                              >>> 0==False[/color][/color][/color]
                              True[color=blue][color=green][color=darkred]
                              >>>[/color][/color][/color]

                              so I guess nothing is wrong :)
                              --
                              Robin Becker

                              Comment

                              Working...