what is the keyword "is" for?


D

daniel

I'm so confused by the keyword "is" and "==" equal sign, it seems they
could be exchanged in some contexts, but not in others, what's the
difference between them in terms of comparation?

thanks...

daniel
 
Ad

Advertisements

S

Sybren Stuvel

daniel enlightened us with:
I'm so confused by the keyword "is" and "==" equal sign, it seems
they could be exchanged in some contexts, but not in others, what's
the difference between them in terms of comparation?

'is' compares the object's addresses. So if 'a is b' is true, then a
and b are the same object.

'==' compare the object's value. If 'a == b' is true, they represent
the same content.

I'll give you an example. I've written a Sudoku puzzle game. If two
puzzles have the same numbers filled in, then "puzzle1 == puzzle2" is
true. They could be two different puzzles, though, which just happen
to have the same numbers filled in. In that case, "puzzle1 is puzzle2"
is false.

Obviously "a is b" implies "a == b", but not the other way around.

Sybren
 
K

Kirk McDonald

daniel said:
I'm so confused by the keyword "is" and "==" equal sign, it seems they
could be exchanged in some contexts, but not in others, what's the
difference between them in terms of comparation?

thanks...

daniel

'is' compares object identity. == compares values.
>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b False
>>> a == b
True

In this example, a and b refer to two separate lists that happen to hold
the same values. Thus, 'is' returns False, and == returns True. On the
other hand:
>>> c = d = [4, 5, 6]
>>> c is d True
>>> c == d
True

Here, c and d refer to the same list. Therefore, 'is' returns true (they
both refer to the same object), as does == (an object is always equal to
itself, unless you overload the equality check in a weird way).

The distinction can easily be seen if we try to mutate these lists:
True

When we mutate a, b is not affected. They are two different lists, and
changing 'a' makes it so they are no longer equal.

When we mutate c, d IS affected; they refer to the same list.

You can easily confuse yourself if you ever talk about applying 'is' to
(for example) integers. Python may re-use certain small integers when
you might not expect it to; this is done in the interests of efficiency.
If you only compare the /values/ of numbers (with ==), then you will
never notice this.
False

-Kirk McDonald
 
D

daniel

many thanks to Sybren and Kirk for your helpful explanation.

when I tried to check the stuff out, found sth interesting that if you
define variables in a style like this:
a = b = ['a', 'b']
changing one list affects the other, and they still refer to same
object. in fact, seems all compound types (dictionary for instance)
behave in this way.

however, when list is replaced with other built-in types like integers
:
a = b = 3
changing one of them cause the two objects differ...


best regards.

daniel
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

daniel said:
when I tried to check the stuff out, found sth interesting that if you
define variables in a style like this:
a = b = ['a', 'b']
changing one list affects the other, and they still refer to same
object. in fact, seems all compound types (dictionary for instance)
behave in this way.

however, when list is replaced with other built-in types like integers
:
a = b = 3
changing one of them cause the two objects differ...

Ah, but make a difference between "change a variable", and "change an
object".

py> a = b = [1,2,3]
py> a[0] = 6 # don't change the variable a, just change the object
py> a
[6, 2, 3]
py> b
[6, 2, 3]
py> a=[7,8,9] # change the variable a;
# it's now a different object than b
py> a
[7, 8, 9]
py> b
[6, 2, 3]

For some objects, "change the object" is impossible. If you have

a = b = 3

then there is no way to change the object 3 to become 4 (say);
integer objects are "immutable". So for these, to make a change,
you really have to change the variable, not the value.

Regards,
Martin
 
D

daniel

Martin said:
daniel said:
when I tried to check the stuff out, found sth interesting that if you
define variables in a style like this:
a = b = ['a', 'b']
changing one list affects the other, and they still refer to same
object. in fact, seems all compound types (dictionary for instance)
behave in this way.

however, when list is replaced with other built-in types like integers
:
a = b = 3
changing one of them cause the two objects differ...

Ah, but make a difference between "change a variable", and "change an
object".

py> a = b = [1,2,3]
py> a[0] = 6 # don't change the variable a, just change the object
py> a
[6, 2, 3]
py> b
[6, 2, 3]
py> a=[7,8,9] # change the variable a;
# it's now a different object than b
mm, python runtime might allocate a new chunk of memory for this... but
might not for the previous operation..
py> a
[7, 8, 9]
py> b
[6, 2, 3]

For some objects, "change the object" is impossible. If you have

a = b = 3

then there is no way to change the object 3 to become 4 (say);
integer objects are "immutable". So for these, to make a change,
you really have to change the variable, not the value.
sounds reasonable, I tried tuple which is also immutable, it behaves
the same as integers.
Regards,
Martin

tks Martin...
 
Ad

Advertisements

S

Steve Holden

daniel said:
Martin v. Löwis wrote: [...]
For some objects, "change the object" is impossible. If you have

a = b = 3

then there is no way to change the object 3 to become 4 (say);
integer objects are "immutable". So for these, to make a change,
you really have to change the variable, not the value.

sounds reasonable, I tried tuple which is also immutable, it behaves
the same as integers.
Well spotted. Tuples are indeed immutable, as are strings, unicode
strings, integers and floats.

regards
Steve
 
T

Terry Reedy

Sybren Stuvel said:
'is' compares the object's addresses.

It actually compares the objects' integer identifiers. That happens to be
the linear memory address for CPython, but not necesarily so for other
interpreters.

tjr
 
D

Dan Bishop

Steve said:
daniel said:
Martin v. Löwis wrote: [...]
For some objects, "change the object" is impossible. If you have

a = b = 3

then there is no way to change the object 3 to become 4 (say);
integer objects are "immutable". So for these, to make a change,
you really have to change the variable, not the value.

sounds reasonable, I tried tuple which is also immutable, it behaves
the same as integers.
Well spotted. Tuples are indeed immutable, as are strings, unicode
strings, integers and floats.

But tuples can contain mutable objects.
(0, [1, 2])
 
H

Hendrik van Rooyen

| Sybren Stuvel wrote [on the difference between is and ==]:
| > Obviously "a is b" implies "a == b",
|
| Not necessarily.
|
| >>> a = b = 1e1000 / 1e1000
| >>> a is b
| True
| >>> a == b
| False

Huh? - wtf is this - I find this deeply disturbing - Sybren's explanation kind
of was congruent with my own understanding, and this is just weird - Hendrik
 
Ad

Advertisements

S

Sybren Stuvel

Dan Bishop enlightened us with:

If "a is b" then they refer to the same object, hence a == b. It
cannot be otherwise, unless Python starts to defy logic. I copied your
code and got the expected result:
True

Sybren
 
S

sjdevnull

Sybren said:
Dan Bishop enlightened us with:

If "a is b" then they refer to the same object, hence a == b. It
cannot be otherwise, unless Python starts to defy logic. I copied your
code and got the expected result:

True

Probably depends on the implementation. 1e1000/1e1000 yields a NaN
here, and I get True for "a is b" but False for "a==b". Presumably
comparing a NaN for equality (any comparison?) always yields False.
 
S

Simon Forman

Sybren said:
Dan Bishop enlightened us with:

If "a is b" then they refer to the same object, hence a == b. It
cannot be otherwise, unless Python starts to defy logic. I copied your
code and got the expected result:

True

Sybren

Python 2.4.3 (#2, Apr 27 2006, 14:43:58)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

|>> a = b = 1e1000 / 1e1000
|>> a is b
True
|>> a == b
False

Huh. Weird. I copied it too and got the "wrong" result.
 
M

Marc 'BlackJack' Rintsch

Dan Bishop enlightened us with:

If "a is b" then they refer to the same object, hence a == b. It
cannot be otherwise, unless Python starts to defy logic. I copied your
code and got the expected result:

True

I get the same as Dan:

In [13]: a = b = 1e1000 / 1e1000

In [14]: a is b
Out[14]: True

In [15]: a == b
Out[15]: False

In [16]: a
Out[16]: nan

On my platform the division results in "Not A Number". Two NaNs compared
are always `False`. You could argue that this is the very same NaN but to
get this effect the interpreter has to take care that every NaN produced
while a program is running is unique. Quite huge overhead for such a
corner case IMHO.

Ciao,
Marc 'BlackJack' Rintsch
 
S

Sybren Stuvel

(e-mail address removed) enlightened us with:
Probably depends on the implementation. 1e1000/1e1000 yields a NaN
here, and I get True for "a is b" but False for "a==b". Presumably
comparing a NaN for equality (any comparison?) always yields False.

Yes, of course. My statement can easily be proven wrong:
.... def __eq__(self, other):
.... return False
....
I also get the same as you folks when I execute the 1e1000/1e1000 test
on my AMD PC. On my Sharp Zaurus SL-C3000 however, it returned the
result I posted earlier.

Sybren
 
Ad

Advertisements

D

Dan Sommers

In [14]: a is b
Out[14]: True
In [15]: a == b
Out[15]: False
In [16]: a
Out[16]: nan
On my platform the division results in "Not A Number". Two NaNs
compared are always `False`. You could argue that this is the very
same NaN but to get this effect the interpreter has to take care that
every NaN produced while a program is running is unique. Quite huge
overhead for such a corner case IMHO.

The interpreter isn't doing anything special; nans have [the equivalent
of] an __eq__ method that always returns False.

Regards,
Dan
 
S

Sion Arrowsmith

Simon Forman said:
Python 2.4.3 (#2, Apr 27 2006, 14:43:58)
[GCC 4.0.3 (Ubuntu 4.0.3-1ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.

|>> a = b = 1e1000 / 1e1000
|>> a is b
True
|>> a == b
False

I agree with you:

$ python
Python 2.4.1 (#2, May 5 2005, 11:32:06)
[GCC 3.3.5 (Debian 1:3.3.5-12)] on linux2
Type "help", "copyright", "credits" or "license" for more information.False

Or maybe I don't:

$ python2.3
Python 2.3.5 (#2, Sep 4 2005, 22:01:42)
[GCC 3.3.5 (Debian 1:3.3.5-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.True

See:

http://mail.python.org/pipermail/python-bugs-list/2004-February/022133.html
 
A

Alex Martelli

Sybren Stuvel said:
Dan Bishop enlightened us with:

If "a is b" then they refer to the same object, hence a == b. It
cannot be otherwise, unless Python starts to defy logic. I copied your

Python also needs to respect standards (such as IEEE 754 for
floating-point arithmetic, and the SQL standards) which do specify the
existence of special objects that "are not equal to anything" including
themselves -- Nan and NULL respectively for these two standards.

We're talking about extremely widespread international standards
developed by huge body of professionals which do include professional
logicians, so I doubt they "defy logic". Python tries to delegate FP to
the underlying hardware and SQL to an external relational DB engine, so
it should be as compliant as the pieces of infrastructure it's using --
which seems to me to be a good architectural decision (not just for
speed and ease of coding, but to ensure any anomaly is somebody else's
fault:).


Alex
 
Ad

Advertisements

S

Sybren Stuvel

Alex Martelli enlightened us with:
Python also needs to respect standards (such as IEEE 754 for
floating-point arithmetic, and the SQL standards) which do specify
the existence of special objects that "are not equal to anything"
including themselves -- Nan and NULL respectively for these two
standards.

Yeah I noticed - see my other post with a trivial example of such a
case.

Sybren
 

Top