len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tor Erik Soenvisen

    #1

    len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

    Hi,


    (len(['']) is 1) == (len(['']) == 1) =True

    Is this the case for all numbers? I've tried running the following:

    for i in range(10000):
    for j in range(10000):
    if i != j:
    assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id
    (i))

    which executes fine. Hence, 0-9999 is okey... But this is a relatively
    small range, and sooner or later you probably get two numbers with the same
    id... Thoughts anyone?

    Regards Tor Erik

    PS: For those of you who don't know: keyword is compares object identities
  • Fredrik Lundh

    #2
    Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

    Tor Erik Soenvisen wrote:
    (len(['']) is 1) == (len(['']) == 1) =True
    >
    Is this the case for all numbers?
    I'm not sure what you're asking here, but if you digest the following
    facts, maybe you can answer it yourself:

    1) all objects that exist at the same time have distinct identifies, and
    2) a Python implementation may or may not hand reuse existing immutable
    objects that have the same value when asked to create a new object,
    3) identities are recycled when objects are deleted, and
    4) [] and {} always create a new object every time they're evaluated.

    </F>

    Comment

    • Peter Otten

      #3
      Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

      Tor Erik Soenvisen wrote:
      (len(['']) is 1) == (len(['']) == 1) =True
      >
      Is this the case for all numbers? I've tried running the following:
      >
      for i in range(10000):
                  for j in range(10000):
                      if i != j:
                              assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i,
      (i))
      Shouldn't the test in the loop be

      if i == j:
      assert i is j


      Of course it would fail...

      Peter

      Comment

      • Fredrik Lundh

        #4
        Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

        distinct identifies

        don't trust your spellchucker.

        </F>

        Comment

        • Richard Brodie

          #5
          Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?


          "Tor Erik Soenvisen" <toreriks@hotma il.comwrote in message
          news:Xns9884782 092A96toreriknp olarno@129.242. 5.222...
          which executes fine. Hence, 0-9999 is okey... But this is a relatively
          small range, and sooner or later you probably get two numbers with the same
          id... Thoughts anyone?
          I think you are confusing yourself unnecessarily. The obvious way to implement
          unique ids is to return the address of the object. It's very unlikely that two
          different objects share the same address.


          Comment

          • Steven D'Aprano

            #6
            Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

            On Thu, 23 Nov 2006 10:48:32 +0000, Tor Erik Soenvisen wrote:
            Hi,
            >
            >
            (len(['']) is 1) == (len(['']) == 1) =True
            You shouldn't rely on this behaviour:
            >>x = 100000
            >>len('a' * x) == x
            True
            >>len('a' * x) is x
            False

            (Your results may vary -- this depends on the implementation. )


            Is this the case for all numbers? I've tried running the following:
            >
            for i in range(10000):
            for j in range(10000):
            if i != j:
            assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id
            (i))
            >
            which executes fine. Hence, 0-9999 is okey...
            This doesn't necessarily hold for all integers -- again, it depends on the
            implementation, the precise version of Python, and other factors. Don't
            rely on "is" giving the same results as "==".
            >>(1+2+3+4+5)** 7 == 15**7
            True
            >>(1+2+3+4+5)** 7 is 15**7
            False
            But this is a relatively
            small range, and sooner or later you probably get two numbers with the same
            id... Thoughts anyone?
            No, you will never get two objects existing at the same time with the same
            id. You will get two objects that exist at different times with the same
            id, since ids may be reused when the object is deleted.
            PS: For those of you who don't know: keyword is compares object identities
            Exactly. There is no guarantee that any specific integer object "1" must
            be the same object as another integer object "1". It may be, but it isn't
            guaranteed.

            I think the only object that is guaranteed to hold for is None. None is a
            singleton, so there is only ever one instance. Hence, you should test for
            None with "obj is None" rather than ==, because some custom classes may do
            silly things with __eq__:

            class Blank(object):
            """Compares equal to anything false, including None."""
            def __eq__(self, other):
            return not other



            --
            Steven.

            Comment

            • Tor Erik Soenvisen

              #7
              Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

              Steven D'Aprano <steve@REMOVE.T HIS.cybersource .com.auwrote in
              news:pan.2006.1 1.23.11.27.54.9 56445@REMOVE.TH IS.cybersource. com.au:
              On Thu, 23 Nov 2006 10:48:32 +0000, Tor Erik Soenvisen wrote:
              >
              >Hi,
              >>
              >>
              >(len(['']) is 1) == (len(['']) == 1) =True
              >
              You shouldn't rely on this behaviour:
              >
              >>>x = 100000
              >>>len('a' * x) == x
              True
              >>>len('a' * x) is x
              False
              >
              (Your results may vary -- this depends on the implementation. )
              >
              >
              >
              >Is this the case for all numbers? I've tried running the following:
              >>
              >for i in range(10000):
              > for j in range(10000):
              > if i != j:
              > assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id
              >(i))
              >>
              >which executes fine. Hence, 0-9999 is okey...
              >
              This doesn't necessarily hold for all integers -- again, it depends on
              the implementation, the precise version of Python, and other factors.
              Don't rely on "is" giving the same results as "==".
              >
              >>>(1+2+3+4+5)* *7 == 15**7
              True
              >>>(1+2+3+4+5)* *7 is 15**7
              False
              >
              >But this is a relatively
              >small range, and sooner or later you probably get two numbers with
              >the same id... Thoughts anyone?
              >
              No, you will never get two objects existing at the same time with the
              same id. You will get two objects that exist at different times with
              the same id, since ids may be reused when the object is deleted.
              >
              >PS: For those of you who don't know: keyword is compares object
              >identities
              >
              Exactly. There is no guarantee that any specific integer object "1"
              must be the same object as another integer object "1". It may be, but
              it isn't guaranteed.
              >
              I think the only object that is guaranteed to hold for is None. None
              is a singleton, so there is only ever one instance. Hence, you should
              test for None with "obj is None" rather than ==, because some custom
              classes may do silly things with __eq__:
              >
              class Blank(object):
              """Compares equal to anything false, including None."""
              def __eq__(self, other):
              return not other
              >
              >
              I've seen code like this:

              if type([]) is list:
              print 'Is list'

              which seem to work. And also I've seen "var is None", as you mention.

              Comment

              • Duncan Booth

                #8
                Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                Steven D'Aprano wrote:
                No, you will never get two objects existing at the same time with the
                same id. You will get two objects that exist at different times with
                the same id, since ids may be reused when the object is deleted.
                >
                I think it is worth pointing out that this is an area where people get
                confused quite often; it is very easily to get misleading results when you
                call the id() function. e.g.
                >>class C:
                def f(self): pass
                def g(self): pass

                >>c = C()
                >>id(c.f)==id(c .g)
                True
                >>c.f is c.g
                False

                The ids are the same here only because the objects do not exist at the same
                time. In the first comparison c.f is an expression which creates a
                temporary object that is destroyed before the expression involving c.g is
                evaluated, so it is possible for the different objects to have the same id.
                In the second comparison the objects exist at the same time so they are
                forced to have different ids.

                Comment

                • Duncan Booth

                  #9
                  Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                  Tor Erik Soenvisen <toreriks@hotma il.comwrote:
                  I've seen code like this:
                  >
                  if type([]) is list:
                  print 'Is list'
                  >
                  which seem to work.
                  'seem to work' is correct. Occasionally 'type(x) is list' is exactly what
                  is needed, but much more likely it is a potential bug.

                  It is more likely that what was intended was: isinstance(x, list)

                  It is even more likely that the intention was that the object should have
                  some list-like behaviour, in which case not doing a test at all is the
                  correct behaviour; or quite often that the object should be list-like but
                  not a string in which case testing the type against basestring would be
                  correct. e.g.:

                  if isinstance(x, basestring):
                  x = [x]
                  # ... now just assume x is a suitable sequence ...
                  for element in x:
                  ...

                  Comment

                  • Fredrik Lundh

                    #10
                    Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                    Tor Erik Soenvisen wrote:
                    I've seen code like this:
                    >
                    if type([]) is list:
                    print 'Is list'
                    >
                    which seem to work. And also I've seen "var is None", as you mention.
                    None is guaranteed to be a singleton:



                    Why "is" works for type objects should be pretty obvious, of course.

                    </F>



                    Comment

                    • Stefan Behnel

                      #11
                      Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                      Tor Erik Soenvisen wrote:
                      (len(['']) is 1) == (len(['']) == 1) =True
                      >>len([''])
                      1
                      >>len(['']) is 1
                      True
                      >>len(['']) == 1
                      True
                      >>True == True
                      True
                      >>(len(['']) is 1) == (len(['']) == 1)
                      True


                      What did you expect?

                      Stefan

                      Comment

                      • Brian Quinlan

                        #12
                        Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                        Fredrik Lundh wrote:
                        4) [] and {} always create a new object every time they're evaluated.
                        Not quite. The empty tuple is cached:
                        >>a = ()
                        >>b = ()
                        >>a is b
                        True

                        Cheers,
                        Brian

                        Comment

                        • Fredrik Lundh

                          #13
                          Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                          Brian Quinlan wrote:
                          >4) [] and {} always create a new object every time they're evaluated.
                          >
                          Not quite. The empty tuple is cached:
                          >
                          >>a = ()
                          >>b = ()
                          >>a is b
                          True
                          () isn't [] or {}, though. time to switch to a bigger font? ;-)

                          </F>

                          Comment

                          • Brian Quinlan

                            #14
                            Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                            Fredrik Lundh wrote:
                            Brian Quinlan wrote:
                            >
                            >>4) [] and {} always create a new object every time they're evaluated.
                            >Not quite. The empty tuple is cached:
                            >>
                            > >>a = ()
                            > >>b = ()
                            > >>a is b
                            >True
                            >
                            () isn't [] or {}, though. time to switch to a bigger font? ;-)
                            Yeah, sorry I'm an idiot. I can't believe that I've been able to program
                            successfully for so long when I can't recognize the different between a
                            dictionary and a tuple :-)

                            Cheers,
                            Brian

                            Comment

                            • Tim Roberts

                              #15
                              Re: len(var) is [CONSTANT] equal to len(var) == [CONSTANT]?

                              Tor Erik Soenvisen <toreriks@hotma il.comwrote:
                              >
                              >(len(['']) is 1) == (len(['']) == 1) =True
                              >
                              >Is this the case for all numbers? I've tried running the following:
                              >
                              >for i in range(10000):
                              for j in range(10000):
                              > if i != j:
                              > assert id(i) != id(j), 'i=%d, j=%d, id=%d' % (i, j, id
                              >(i))
                              >
                              >which executes fine. Hence, 0-9999 is okey... But this is a relatively
                              >small range, and sooner or later you probably get two numbers with the same
                              >id... Thoughts anyone?
                              It has been my experience that virtually every use of the "is" operator
                              (except "is None") is wrong.

                              Now, I fully understand that there are perfectly valid uses for "is", and
                              the standard library contains a few, but for the non-guru casual Python
                              programmer, I think it is safe to say "never use 'is'".
                              --
                              Tim Roberts, timr@probo.com
                              Providenza & Boekelheide, Inc.

                              Comment

                              Working...