Result of ``a is b''

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Axel Boldt

    Result of ``a is b''

    Hello,

    is there a rationale for the following behavior:
    [color=blue][color=green][color=darkred]
    >>> a = (1,2)
    >>> b = (1,2)
    >>> a is b[/color][/color][/color]
    False[color=blue][color=green][color=darkred]
    >>> a = "12"
    >>> b = "12"
    >>> a is b[/color][/color][/color]
    True

    Thanks,
    Axel
  • Andrew Koenig

    #2
    Re: Result of ``a is b''

    "Axel Boldt" <axelboldt@yaho o.com> wrote in message
    news:40200384.0 403151632.35496 ee6@posting.goo gle.com...
    [color=blue]
    > is there a rationale for the following behavior:
    >[color=green][color=darkred]
    > >>> a = (1,2)
    > >>> b = (1,2)
    > >>> a is b[/color][/color]
    > False[color=green][color=darkred]
    > >>> a = "12"
    > >>> b = "12"
    > >>> a is b[/color][/color]
    > True[/color]

    Probably an accident of implementation. Consider:
    [color=blue][color=green][color=darkred]
    >>> a = "1 2"
    >>> b = "1" + " 2"
    >>> a is b[/color][/color][/color]
    False

    and, for that matter:
    [color=blue][color=green][color=darkred]
    >>> a = (1, 2)
    >>> b = a
    >>> a is b[/color][/color][/color]
    True

    Is there a reason that you care about this behavior?


    Comment

    • Erik Max Francis

      #3
      Re: Result of ``a is b''

      Axel Boldt wrote:
      [color=blue]
      > is there a rationale for the following behavior:[/color]

      Yes: It shouldn't matter to you what the implementation is doing.

      --
      __ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
      / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
      \__/ I only regret that I have but one life to lose for my country.
      -- Nathan Hale

      Comment

      • Josiah Carlson

        #4
        Re: Result of ``a is b''

        > >>> a = (1,2)[color=blue][color=green][color=darkred]
        > >>> b = (1,2)
        > >>> a is b[/color][/color]
        > False[color=green][color=darkred]
        > >>> a = "12"
        > >>> b = "12"
        > >>> a is b[/color][/color]
        > True[/color]

        Unless you care whether two names point to the same object, don't use
        'is'. Instead compare for equality with '=='. That should work like
        you want it to:[color=blue][color=green][color=darkred]
        >>> a = (1,2)
        >>> b = (1,2)
        >>> a == b[/color][/color][/color]
        True[color=blue][color=green][color=darkred]
        >>> a = "12"
        >>> b = "12"
        >>> a == b[/color][/color][/color]
        True

        It will also handle the cases that Andrew points out.

        - Josiah

        Comment

        • David MacQuigg

          #5
          Re: Result of ``a is b''

          On 15 Mar 2004 16:32:25 -0800, axelboldt@yahoo .com (Axel Boldt) wrote:
          [color=blue]
          >is there a rationale for the following behavior:
          >[color=green][color=darkred]
          > >>> a = (1,2)
          > >>> b = (1,2)
          > >>> a is b[/color][/color]
          > False[color=green][color=darkred]
          > >>> a = "12"
          > >>> b = "12"
          > >>> a is b[/color][/color]
          > True[/color]

          Here's another one:[color=blue][color=green][color=darkred]
          >>> x = 'akdijfkdienlsk fi'
          >>> y = 'akdijfkdienlsk fi'
          >>> x is y[/color][/color][/color]
          True[color=blue][color=green][color=darkred]
          >>> x = 'a b'
          >>> y = 'a b'
          >>> x is y[/color][/color][/color]
          False[color=blue][color=green][color=darkred]
          >>> x == y[/color][/color][/color]
          True[color=blue][color=green][color=darkred]
          >>>[/color][/color][/color]

          It has to do with how Python decides which strings to "internaliz e"
          and make shared objects in order to save space. This is only a
          problem with immutable objects. Others cannot be shared like this.

          My suggestion is to *never* use 'is' with these objects unless you
          really need the fact that it is faster than '==' and you test it
          thoroughly for the kind of objects you will be comparing.

          -- Dave

          Comment

          • Skip Montanaro

            #6
            Re: Result of ``a is b''


            Axel> is there a rationale for the following behavior:
            [color=blue][color=green][color=darkred]
            >>> a = (1,2)
            >>> b = (1,2)
            >>> a is b[/color][/color][/color]
            False[color=blue][color=green][color=darkred]
            >>> a = "12"
            >>> b = "12"
            >>> a is b[/color][/color][/color]
            True

            Sure. The "is" operator doesn't do an element-by-element comparison of the
            two objects. It only compares the memory addresses of the two objects being
            compared. The difference between the tuple case and the string case is that
            string literals which look roughly like identifiers (no spaces, all letters,
            digits or underscores) are automatically interned and are thus shared. As
            Andrew Koenig indicated, it's an implementation detail. It improves
            performance to intern identifiers and it's not worth the extra expense to
            decide if a string literal is really being used as a variable name, so all
            strings which look structurally like identifiers are interned. You should
            generally only use "is" to compare objects against known singleton objects:
            None, True, False and Ellipsis. Use "==" for everything else.

            Skip

            Comment

            • John Roth

              #7
              Re: Result of ``a is b''

              "David MacQuigg" <dmq@gain.com > wrote in message
              news:gjvc50pkfb 1ofgmfd1p39vcsj 1g97un7d8@4ax.c om...[color=blue]
              > On 15 Mar 2004 16:32:25 -0800, axelboldt@yahoo .com (Axel Boldt) wrote:
              >[color=green]
              > >is there a rationale for the following behavior:
              > >[color=darkred]
              > > >>> a = (1,2)
              > > >>> b = (1,2)
              > > >>> a is b[/color]
              > > False[color=darkred]
              > > >>> a = "12"
              > > >>> b = "12"
              > > >>> a is b[/color]
              > > True[/color]
              >
              > Here's another one:[color=green][color=darkred]
              > >>> x = 'akdijfkdienlsk fi'
              > >>> y = 'akdijfkdienlsk fi'
              > >>> x is y[/color][/color]
              > True[color=green][color=darkred]
              > >>> x = 'a b'
              > >>> y = 'a b'
              > >>> x is y[/color][/color]
              > False[color=green][color=darkred]
              > >>> x == y[/color][/color]
              > True[color=green][color=darkred]
              > >>>[/color][/color]
              >
              > It has to do with how Python decides which strings to "internaliz e"
              > and make shared objects in order to save space. This is only a
              > problem with immutable objects. Others cannot be shared like this.
              >
              > My suggestion is to *never* use 'is' with these objects unless you
              > really need the fact that it is faster than '==' and you test it
              > thoroughly for the kind of objects you will be comparing.[/color]

              I'd go a slightly different direction on this: "is" is for physical
              identity, "==" is for semantic equivalence. Never mix the two.
              You cannot guarantee physical identity across different releases
              of CPython, let alone between CPython and Jython (Python on the
              Java VM), IronPython (the experimental Python on the .Net CLR)
              or PyPy (the even more experimental attempt to rewrite Python in
              Python.) And I'm sure I've left out a couple of other environments.

              Using "is" is appropriate in only two circumstances:

              1) when you're checking if an object you created is bound to
              an identifer that's under your control,

              and

              2) when you're checking one of the few objects that are guaranteed
              by the Python specs to be singletons: None, True and False are the
              standard suspects in this case.

              John Roth

              [color=blue]
              >
              > -- Dave
              >[/color]


              Comment

              • Axel Boldt

                #8
                Re: Result of ``a is b''

                David MacQuigg <dmq@gain.com > wrote
                [color=blue][color=green][color=darkred]
                > >>> x = 'akdijfkdienlsk fi'
                > >>> y = 'akdijfkdienlsk fi'
                > >>> x is y[/color][/color]
                > True[color=green][color=darkred]
                > >>> x = 'a b'
                > >>> y = 'a b'
                > >>> x is y[/color][/color]
                > False[/color]

                Wow. So it seems that the action of "is" on immutables is unspecified
                and implementation dependent, thus useless to the programmer.

                Maybe one could redefine "is" on immutables as follows: for strings
                and numbers it acts as "==", for tuples it acts as componentwise "is".
                That would be a more useful operator IMHO.

                Axel

                Comment

                • Peter Hansen

                  #9
                  Re: Result of ``a is b''

                  Axel Boldt wrote:
                  [color=blue]
                  > David MacQuigg <dmq@gain.com > wrote
                  >
                  >[color=green][color=darkred]
                  >>>>>x = 'akdijfkdienlsk fi'
                  >>>>>y = 'akdijfkdienlsk fi'
                  >>>>>x is y[/color]
                  >>
                  >> True
                  >>[color=darkred]
                  >>>>>x = 'a b'
                  >>>>>y = 'a b'
                  >>>>>x is y[/color]
                  >>
                  >> False[/color]
                  >
                  >
                  > Wow. So it seems that the action of "is" on immutables is unspecified
                  > and implementation dependent, thus useless to the programmer.[/color]

                  Absolutely not! "is" does what it does, and the definition of what it
                  does is very explicit. It checks *identity*, not equality. In both
                  examples above, the code is semantically meaningless because you are
                  checking identity on two things which you just created at the command
                  line, out of thin air. They may or may not be identical, but whether
                  they are or not has no importance.

                  I'm not being very clear, but what I mean is that "is" should be used
                  when *identity* is important to you. For example, you have a particular
                  object and you want to check whether a method call returns that
                  particular object, perhaps as a "sentinel" value. "is" is what you want
                  here, because you are checking whether *that specific object* is being
                  returned, not whether the returned item equals that object in value.

                  There are very good (and correct) times to use "is", but the trivial
                  examples above aren't them...

                  -Peter

                  Comment

                  • Skip Montanaro

                    #10
                    Re: Result of ``a is b''

                    >>>>> "Axel" == Axel Boldt <axelboldt@yaho o.com> writes:

                    Axel> David MacQuigg <dmq@gain.com > wrote[color=blue][color=green][color=darkred]
                    >> >>> x = 'akdijfkdienlsk fi'
                    >> >>> y = 'akdijfkdienlsk fi'
                    >> >>> x is y[/color]
                    >> True[color=darkred]
                    >> >>> x = 'a b'
                    >> >>> y = 'a b'
                    >> >>> x is y[/color]
                    >> False[/color][/color]

                    Axel> Wow. So it seems that the action of "is" on immutables is
                    Axel> unspecified and implementation dependent, thus useless to the
                    Axel> programmer.

                    No, its behavior is quite well-specified. It does a pointer comparison.
                    Here is my "is" rule:

                    Use "is" to compare two objects only if one is explicitly known to be a
                    singleton defined by the language (None, Ellipsis, True, False).

                    and its corrolary:

                    Never use "is" to compare two programmer-defined variables.

                    Note that even though I "know" that small integers, identifier-like strings
                    and the null tuple are all shared objects, the language implementation is
                    free to change. Those are simply optimizations which you can't rely on.
                    Use "==" when comparing integers, strings and tuples.

                    Trying to use "is" when you want a performance improvement is generally
                    unwise. There is a performance hit going from "is" to "==", but it's
                    probably going be down in the noise compared to all the other things a
                    significant program needs to do. Ordered from fastest to slowest, timing a
                    pass statement, "a is b", "a == b" and a call to a function that only
                    executes a pass statement:

                    % timeit.py -s "a = b = 'frankie and johnny'" "pass"
                    10000000 loops, best of 3: 0.132 usec per loop
                    % timeit.py -s "a = b = 'frankie and johnny'" "a is b"
                    1000000 loops, best of 3: 0.372 usec per loop
                    % timeit.py -s "a = b = 'frankie and johnny'" "a == b"
                    1000000 loops, best of 3: 0.491 usec per loop
                    % timeit.py -s "def f(): pass" "f()"
                    1000000 loops, best of 3: 1.1 usec per loop

                    "a == b" is still twice as fast as a null function call.

                    Moral of the story: stop writing code that contains so many
                    functions. <wink>

                    Skip

                    Comment

                    • David M. Cooke

                      #11
                      Re: Result of ``a is b''

                      At some point, axelboldt@yahoo .com (Axel Boldt) wrote:
                      [color=blue]
                      > David MacQuigg <dmq@gain.com > wrote
                      >[color=green][color=darkred]
                      >> >>> x = 'akdijfkdienlsk fi'
                      >> >>> y = 'akdijfkdienlsk fi'
                      >> >>> x is y[/color]
                      >> True[color=darkred]
                      >> >>> x = 'a b'
                      >> >>> y = 'a b'
                      >> >>> x is y[/color]
                      >> False[/color][/color]

                      And you get different results in different contexts:
                      In [17]: def f():
                      ....: x = 'a b'
                      ....: y = 'a b'
                      ....: return x is y
                      ....:
                      In [18]: f()
                      Out[18]: True
                      [color=blue]
                      > Wow. So it seems that the action of "is" on immutables is unspecified
                      > and implementation dependent, thus useless to the programmer.[/color]

                      No, it's entirely specified. 'is' is 'is the same object'. The
                      implementation-specific part is in the *creation* of the immutable
                      object: when you specify 'akdijfkdienlsk fi' in your code twice, the
                      interned object is used the second time -- so you actually only have
                      one object. In my example above, the compiler knew 'a b' was
                      duplicated, so it only has one copy of 'a b' stored in the function object.
                      [color=blue]
                      > Maybe one could redefine "is" on immutables as follows: for strings
                      > and numbers it acts as "==", for tuples it acts as componentwise "is".
                      > That would be a more useful operator IMHO.[/color]

                      Why? If what you need is equality, and not object identity, use '=='.

                      Personally, almost all my uses of 'is' are of the form 'x is None' or
                      'x is not None'.

                      --
                      |>|\/|<
                      /--------------------------------------------------------------------------\
                      |David M. Cooke
                      |cookedm(at)phy sics(dot)mcmast er(dot)ca

                      Comment

                      • Erik Max Francis

                        #12
                        Re: Result of ``a is b''

                        Axel Boldt wrote:
                        [color=blue]
                        > David MacQuigg <dmq@gain.com > wrote
                        >[color=green][color=darkred]
                        > > >>> x = 'akdijfkdienlsk fi'
                        > > >>> y = 'akdijfkdienlsk fi'
                        > > >>> x is y[/color]
                        > > True[color=darkred]
                        > > >>> x = 'a b'
                        > > >>> y = 'a b'
                        > > >>> x is y[/color]
                        > > False[/color]
                        >
                        > Wow. So it seems that the action of "is" on immutables is unspecified
                        > and implementation dependent, thus useless to the programmer.[/color]

                        It's less useful for testing mere equivalence, yes, because that's not
                        what it's intended to do. It tests identity. Here whether the two
                        strings are not just equal but _identical objects_ is an implementation
                        detail. If you ever rely on this behavior, your code will not be
                        portable to other implementations of Python.

                        --
                        __ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
                        / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
                        \__/ Here day fights with night.
                        -- (the last words of Victor Hugo)

                        Comment

                        • Erik Max Francis

                          #13
                          Re: Result of ``a is b''

                          Skip Montanaro wrote:
                          [color=blue]
                          > Here is my "is" rule:
                          >
                          > Use "is" to compare two objects only if one is explicitly known to
                          > be a
                          > singleton defined by the language (None, Ellipsis, True, False).[/color]

                          I'd add "or defined by the programmer within his code." Although
                          admittedly I don't use it that way much.

                          --
                          __ Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
                          / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
                          \__/ Here day fights with night.
                          -- (the last words of Victor Hugo)

                          Comment

                          • David MacQuigg

                            #14
                            Re: Result of ``a is b''

                            On Tue, 16 Mar 2004 18:00:04 -0500, cookedm+news@ph ysics.mcmaster. ca
                            (David M. Cooke) wrote:
                            [color=blue]
                            >Personally, almost all my uses of 'is' are of the form 'x is None' or
                            >'x is not None'.[/color]

                            Here are some more test results (averaging 10,000 evaluations in a
                            tight loop):

                            time (sec) %
                            Test 1: 3.68E-007 100.0 F is False
                            Test 2: 4.87E-007 132.1 F == False
                            Test 3: 3.71E-007 100.0 N is None
                            Test 4: 5.51E-007 148.6 N == None

                            The '== None' test is 49% slower than 'is None', but in absolute time,
                            the difference is only 180nec (on my new, but not top-speed PC). So
                            it would take about 10 million of these comparisons in a short time to
                            make a noticable difference to the user.

                            I can't see where the 'is' test would *ever* be needed for the above
                            comparisons.

                            -- Dave

                            Comment

                            • Andrew Koenig

                              #15
                              Re: Result of ``a is b''

                              "Axel Boldt" <axelboldt@yaho o.com> wrote in message
                              news:40200384.0 403161255.7fca7 a8c@posting.goo gle.com...
                              [color=blue]
                              > Wow. So it seems that the action of "is" on immutables is unspecified
                              > and implementation dependent, thus useless to the programmer.[/color]

                              Hardly. It has two fundamental properties, which can sometimes be useful:

                              1) If x and y refer to the same object, "x is y" yields True.

                              2) If "x is y" yields True, "x==y" also yields True. Equivalently, if
                              "x==y" yields False, "x is y" also yields False.
                              [color=blue]
                              > Maybe one could redefine "is" on immutables as follows: for strings
                              > and numbers it acts as "==", for tuples it acts as componentwise "is".
                              > That would be a more useful operator IMHO.[/color]

                              Can you give a realistic example of code that would benefit from such a
                              change?


                              Comment

                              Working...