Difference between 'is' and '=='

M

mwql

Hey guys, this maybe a stupid question, but I can't seem to find the
result anywhere online. When is the right time to use 'is' and when
should we use '=='?

Thanks alot~
 
M

Max M

mwql said:
Hey guys, this maybe a stupid question, but I can't seem to find the
result anywhere online. When is the right time to use 'is' and when
should we use '=='?

"is" is like id(obj1) == id(obj2)
False

They don't have the same id. (Think of id as memory adresses.)

--

hilsen/regards Max M, Denmark

http://www.mxm.dk/
IT's Mad Science

Phone: +45 66 11 84 94
Mobile: +45 29 93 42 96
 
F

Fuzzyman

mwql said:
Hey guys, this maybe a stupid question, but I can't seem to find the
result anywhere online. When is the right time to use 'is' and when
should we use '=='?

Thanks alot~

'==' is the equality operator. It is used to test if two objects are
'equal'.

'is' is the identity operator, it is used to test if two
names/references point to the same object.

a = {'a': 3}
b = {'a': 3}
a == b
True
a is b
False
c = a
a is c
True

The two dictionaries a and b are equal, but are separate objects.
(Under the hood, Python uses 'id' to determine identity).

When you bind another name 'c' to point to dictionary a, they *are* the
same object - so a *is* c.

One place the 'is' operator is commonly used is when testing for None.
You only ever have one instance of 'None', so

a is None

is quicker than

a == None

(It only needs to check identity not value.)

I hope that helps.

Fuzzyman
http://www.voidspace.org.uk/python/index.shtml
 
J

Joel Hedlund

"is" is like id(obj1) == id(obj2)
(Think of id as memory adresses.)

Which means that "is" comparisons in general will be faster than ==
comparisons. According to PEP8 (python programming style guidelines) you should
use 'is' when comparing to singletons like None. I take this to also include
constants and such. That allows us to take short cuts through known terrain,
such as in the massive_computations function below:

--------------------------------------------------------------
import time

class LotsOfData(object):
def __init__(self, *data):
self.data = data
def __eq__(self, o):
time.sleep(2) # time consuming computations...
return self.data == o.data

KNOWN_DATA = LotsOfData(1,2)
same_data = KNOWN_DATA
equal_data = LotsOfData(1,2)
other_data = LotsOfData(2,3)

def massive_computations(data = KNOWN_DATA):
if data is KNOWN_DATA:
return "very quick answer"
elif data == KNOWN_DATA:
return "quick answer"
else:
time.sleep(10) # time consuming computations...
return "slow answer"

print "Here we go!"
print massive_computations()
print massive_computations(same_data)
print massive_computations(equal_data)
print massive_computations(other_data)
print "Done."
 
R

Roy Smith

Joel Hedlund said:
Which means that "is" comparisons in general will be faster than ==
comparisons.

I thought that == automatically compared identify before trying to compare
the values. Or am I thinking of some special case, like strings?
 
P

Peter Hansen

Roy said:
I thought that == automatically compared identify before trying to compare
the values. Or am I thinking of some special case, like strings?

You must be thinking of a special case:
.... def __cmp__(self, other): return 1
....False


-Peter
 
C

Clemens Hepper

Roy said:
I thought that == automatically compared identify before trying to compare
the values. Or am I thinking of some special case, like strings?

Even for strings there is a performance difference:
0.21730494499206543

mfg
- eth
 
D

Dan Sommers

... According to PEP8 (python programming style guidelines) you should
use 'is' when comparing to singletons like None. I take this to also
include constants and such ...

This does *not* also mean constants and such:

Python 2.4.2 (#1, Feb 22 2006, 08:02:53)
[GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Regards,
Dan
 
M

mwql

It's really strange,

if
a = 1
b = 1
a is b ==> True

the same thing applies for strings, but not for dict, lists or tuples
I think the 'is' operator is useful for objects only, not for primitive
types,
I think I solved the mystery behind my bugged code =)
 
C

Clemens Hepper

Dan said:
This does *not* also mean constants and such:

Python 2.4.2 (#1, Feb 22 2006, 08:02:53)
[GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
Type "help", "copyright", "credits" or "license" for more information.False

It's strange: python seem to cache constants from 0 to 99:

for x in xrange(1000):
if not eval("%d"%x) is eval("%d"%x):
print x

for me it printed 100-999.

- eth
 
D

Diez B. Roggisch

mwql said:
It's really strange,

if
a = 1
b = 1
a is b ==> True

the same thing applies for strings, but not for dict, lists or tuples
I think the 'is' operator is useful for objects only, not for primitive
types,
I think I solved the mystery behind my bugged code =)

The reason that "is" works for small numbers is that these are cached for
performance reasons. Try
False

So - your conclusion is basically right: use is on (complex) objects, not on
numbers and strings and other built-ins. The exception from the rule is
None - that should only exist once, so

foo is not None

is considered better style than foo == None.

Diez
 
F

Felipe Almeida Lessa

Em Seg, 2006-03-27 às 08:23 -0500, Dan Sommers escreveu:
... According to PEP8 (python programming style guidelines) you should
use 'is' when comparing to singletons like None. I take this to also
include constants and such ...

This does *not* also mean constants and such:

Python 2.4.2 (#1, Feb 22 2006, 08:02:53)
[GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

Not those kind of constants, but this one:

Python 2.4.2 (#2, Nov 20 2005, 17:04:48)
[GCC 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
 
D

Donn Cave

"Diez B. Roggisch said:
So - your conclusion is basically right: use is on (complex) objects, not on
numbers and strings and other built-ins. The exception from the rule is
None - that should only exist once, so

foo is not None

is considered better style than foo == None.

But even better style is just `foo' or `not foo'. Or not,
depending on what you're thinking.

The key point between `is' and `==' has already been made -
- use `is' to compare identity
- use `==' to compare value

It's that simple, and it's hard to add to this without
potentially layering some confusion on it. While Python's
implementation makes the use of identity with small numbers
a slightly more complicated issue, there isn't a lot of
practical difference. To take a common case that has already
been mentioned here, if I define some constant symbolic values
as small integers, as long as I take care that their values
are distinct, I can reasonably use identity and ignore this
technical weakness. I can assume that no one is going to
supply randomly selected integers in this context. Meanwhile,
the use of identity clarifies the intent.

Depending, of course, on what the intent may be, which brings
us to None, and a point about values in Python that was brought
to a fairly brilliant light some years back by someone we don't
hear from often here any more, unfortunately.

- use `is' to compare identity
- use `==' to compare value
- use neither to test for `somethingness'

I'm not going to try to elucidate the theory of something and
nothing in Python, but suffice it to say that there are places
where it may be better to write

if not expr:

than

if expr is None:

or worse yet,

if expr == False:

That's what I think, anyway.

Donn Cave, (e-mail address removed)
 
T

Terry Reedy

It's strange: python seem to cache constants from 0 to 99:

The Python specification allows but does not require such behind-the-scenes
implementation optimization hacks. As released, CPython 2.4 caches -5 to
99, I believe. In 2.5, the upper limit was increased to 256. The limits
are in a pair of #define statements in the int object source file. Anyone
who compiles from source can adjust as desired (though the corresponding
test will fail unless also adjusted ;-).

I think the visibility of this implementation detail from Python code is an
example of a leaky abstraction. For more, see
http://www.joelonsoftware.com/articles/LeakyAbstractions.html

Terry Jan Reedy
 
E

Erik Max Francis

Terry said:
The Python specification allows but does not require such behind-the-scenes
implementation optimization hacks. As released, CPython 2.4 caches -5 to
99, I believe. In 2.5, the upper limit was increased to 256. The limits
are in a pair of #define statements in the int object source file. Anyone
who compiles from source can adjust as desired (though the corresponding
test will fail unless also adjusted ;-).

I think the visibility of this implementation detail from Python code is an
example of a leaky abstraction. For more, see
http://www.joelonsoftware.com/articles/LeakyAbstractions.html

I don't see that as quite the same thing. That you can fiddle around
with the `is` operator to investigate how small integers are cached
doesn't really reveal any profound underlying abstraction, except that
maybe all Python entities are true objects and that integers are
immutable, which are things hopefully everyone was already aware of.

If you're trying to test integer equality, you should be using the `==`
operator, not the `is` operator, so what you find out about how things
are caching is really irrelevant.
 
R

Rene Pijlman

Terry Reedy:
The Python specification allows but does not require such behind-the-scenes
implementation optimization hacks. As released, CPython 2.4 caches -5 to
99, I believe. In 2.5, the upper limit was increased to 256. The limits
are in a pair of #define statements in the int object source file. Anyone
who compiles from source can adjust as desired (though the corresponding
test will fail unless also adjusted ;-).

I think the visibility of this implementation detail from Python code is an
example of a leaky abstraction. For more, see
http://www.joelonsoftware.com/articles/LeakyAbstractions.html

Joel has his abstractions wrong. TCP doesn't guarantee reliable delivery,
unlike IP it delivers reliably or it tells you it cannot. SQL perormance
doesn't break abstraction, since performance isn't part of SQL. You _can_
drive as fast when it's raining.

Now, about identity and equality. As you know, identity implies equality,
but equality doesn't imply identity. You seem to assume that when identity
is not implied, it should be undetectable. But why?

Here's A, there's B, they may or may not be identical, they may or may not
be equal.

What are you suggesting?

1. If A and B are of comparable types, and A equals B, we should not be
allowed to evaluate "A is B".

2. If A and B are of comparable types, and A equals B, A should be B.

3. If A and B are of comparable types, and A equals B, A should not be B.

4. If A and B are of comparable types, and A equals B, "A is B" should not
evaluate to a boolean value.

5. When A and B are of comparable types, we should not be allowed to
evaluate "A == B" :)
 
D

Dan Sommers

Em Seg, 2006-03-27 às 08:23 -0500, Dan Sommers escreveu:
... According to PEP8 (python programming style guidelines) you should
use 'is' when comparing to singletons like None. I take this to also
include constants and such ...

This does *not* also mean constants and such:

Python 2.4.2 (#1, Feb 22 2006, 08:02:53)
[GCC 4.0.1 (Apple Computer, Inc. build 5247)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
a = 123456789
a == 123456789 True
a is 123456789 False

Not those kind of constants, but this one:
Python 2.4.2 (#2, Nov 20 2005, 17:04:48)
[GCC 4.0.3 20051111 (prerelease) (Debian 4.0.2-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

That's a little misleading, and goes back to the questions of "what is
assignment in Python?" and "What does it mean for an object to be
mutable?"

The line "a = CONST" simply gives CONST a new name. After that, "a is
CONST" will be True no matter what CONST was. Under some circumstances,
I can even change CONST, and "a is CONST" will *still* be True.
CONST = range(22)
a = CONST
a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
a is CONST True
CONST[12] = 'foo'
a is CONST True

Right off the top of my head, I can't think of a way to make "a = b; a
is b" return False.

Regards,
Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top