Interesting behaviour of the assignment

Thomas Wouters thomas at xs4all.net
Thu Dec 28 11:32:00 EST 2000


On Thu, Dec 28, 2000 at 07:23:54PM +0900, June Kim wrote:
> >>> a=100
> >>> b=100
> >>> a is b
> 0
> >>> a=99
> >>> b=99
> >>> a is b
> 1

> Is this an intended/expected result? What is the lying structure beneath
> this?

Yes, this is intended. The 'is' operator is the 'identity' operator, it
returns true if and only if the left hand side of the expression refers to
the same object (not similar, not the same type, not equal, but the *same*)
as the right hand side. Numbers below 100 are always 'unique', they are
created only once, cached and reused whenever you need them. Numbers above
and including 100 are not cached like that, but because of the way the
python constants work, all the constants with the same value end up as the
same object, regardless. Unfortunately, the interactive session behaves
slightly different than a script, so you don't see that behaviour there.

Here is an example:

locust:~> cat spam.py
a = 42
b = 42
c = 41+1  
d = 43-1  

e = 666   
f = 666
g = 665+1
h = 667-1

if (a, b, c, d) == (42,)*4:
    print "a, b, c, d are all 42"

print "id(a) =", id(a)
print "id(b) =", id(b)
if a is b:
    print "a is b"
else:
    print "a is not b"

print "id(c) =", id(c)
print "id(d) =", id(d)
if c is d:
    print "c is d"
else:
    print "c is not d"

if (e, f, g, h) == (666,)*4:
    print "e, f, g, h are all 666"

print "id(e) =", id(e)
print "id(f) =", id(f)
if e is f:
    print "e is f"
else:
    print "e is not f"

print "id(g) =", id(g)
print "id(h) =", id(h)
if g is h:
    print "g is h"
else:
    print "g is not h"

locust:~> python spam.py
a, b, c, d are all 42
id(a) = 134528380
id(b) = 134528380
a is b
id(c) = 134528380
id(d) = 134528380
c is d
e, f, g, h are all 666
id(e) = 134657012
id(f) = 134657012
e is f
id(g) = 134656988
id(h) = 134656976
g is not h

(If you cut&paste the above code into an interactive session, you'll see
that it'll claim that 'e is not f'. That's because constants are handled
slightly differently in the interactive read-eval-print-loop.)

End result ? Don't use 'is' unless you really, really need an identity
check, and not a value check. It's a damned fast check (a single pointer
comparison) but it isn't enough if you really mean '==', not 'is'.

-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!




More information about the Python-list mailing list