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

Discussion in 'Python' started by Tor Erik Soenvisen, Nov 23, 2006.

  1. 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
     
    Tor Erik Soenvisen, Nov 23, 2006
    #1
    1. Advertising

  2. 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>
     
    Fredrik Lundh, Nov 23, 2006
    #2
    1. Advertising

  3. > distinct identifies

    don't trust your spellchucker.

    </F>
     
    Fredrik Lundh, Nov 23, 2006
    #3
  4. Tor Erik Soenvisen

    Peter Otten Guest

    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
     
    Peter Otten, Nov 23, 2006
    #4
  5. "Tor Erik Soenvisen" <> wrote in message
    news:Xns9884782092A96toreriknpolarno@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.
     
    Richard Brodie, Nov 23, 2006
    #5
  6. 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.
     
    Steven D'Aprano, Nov 23, 2006
    #6
  7. Steven D'Aprano <> wrote in
    news:p:

    > 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.
     
    Tor Erik Soenvisen, Nov 23, 2006
    #7
  8. Tor Erik Soenvisen

    Duncan Booth Guest

    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.
     
    Duncan Booth, Nov 23, 2006
    #8
  9. Tor Erik Soenvisen

    Duncan Booth Guest

    Tor Erik Soenvisen <> wrote:

    > 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:
    ...
     
    Duncan Booth, Nov 23, 2006
    #9
  10. 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:

    http://effbot.org/pyref/type-none.htm

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

    </F>
     
    Fredrik Lundh, Nov 23, 2006
    #10
  11. 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
     
    Stefan Behnel, Nov 23, 2006
    #11
  12. 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
     
    Brian Quinlan, Nov 23, 2006
    #12
  13. 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>
     
    Fredrik Lundh, Nov 23, 2006
    #13
  14. 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
     
    Brian Quinlan, Nov 23, 2006
    #14
  15. Tor Erik Soenvisen

    Tim Roberts Guest

    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, 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,
    Providenza & Boekelheide, Inc.
     
    Tim Roberts, Nov 23, 2006
    #15
    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. Alvin Bruney

    Threads.. Session var lost, App var ok

    Alvin Bruney, Dec 2, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    373
    rooster575
    Dec 2, 2003
  2. thomson
    Replies:
    10
    Views:
    2,510
    Eliyahu Goldin
    Jun 20, 2005
  3. thomson
    Replies:
    0
    Views:
    396
    thomson
    Jun 20, 2005
  4. Fred
    Replies:
    3
    Views:
    330
    Alf P. Steinbach
    Aug 10, 2003
  5. maestro
    Replies:
    1
    Views:
    312
    Chris
    Aug 11, 2008
Loading...

Share This Page