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

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Thu Nov 23 12:27:55 CET 2006

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
>>> len('a' * x) is x

(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
>>> (1+2+3+4+5)**7 is 15**7

> 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

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


More information about the Python-list mailing list