[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Seemingly odd 'is' comparison.

Tobiah

2/13/2008 10:20:00 PM

>>> print float(3.0) is float(3.0)
True
>>> print float(3.0 * 1.0) is float(3.0)
False
>>>


Thanks,

Tobiah

--
Posted via a free Usenet account from http://www.te...

18 Answers

Arnaud Delobelle

2/18/2008 12:26:00 PM

0

On Feb 13, 10:19 pm, Tobiah <t...@tobiah.org> wrote:
> >>> print float(3.0) is float(3.0)
> True
> >>> print float(3.0 * 1.0) is float(3.0)
> False

[You don't need to wrap your floats in float()]

>>> def f():
... return 3.0 is 3.0, 3.0*1.0 is 3.0
...
>>> f()
(True, False)
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 1 (3.0)
3 LOAD_CONST 1 (3.0)
6 COMPARE_OP 8 (is)
9 LOAD_CONST 3 (3.0)
12 LOAD_CONST 1 (3.0)
15 COMPARE_OP 8 (is)
18 BUILD_TUPLE 2
21 RETURN_VALUE

As you can see when "3.0 is 3.0" is evaluated the same float object is
put on the stack twice so the 'is' comparison is True (LOAD_CONST 1 /
LOAD_CONST 1 / COMPARE_OP 8).

Whereas when "3.0*1.0 is 3.0" is evaluated, *two* different float
objects are put on the stack and compared (LOAD_CONST 3 / LOAD_CONST
1 / COMPARE_OP 8). Therefore the result is False.

HTH

--
Arnaud

Duncan Booth

2/18/2008 12:31:00 PM

0

Tobiah <toby@tobiah.org> wrote:

> Subject: Seemingly odd 'is' comparison.

Please put your question into the body of the message, not just the
headers.

>>>> print float(3.0) is float(3.0)
> True
>>>> print float(3.0 * 1.0) is float(3.0)
> False
>>>>
>
>
> Thanks,
>
> Tobiah
>
Your values are already all floats so float() just returns its arguments.
In other words you can omit it:

>>> 3.0 is 3.0
True
>>> 3.0 * 1.0 is 3.0
False

3.0 used twice in the same compilation unit is the same constant value used
twice. 3.0 * 1.0 creates a new float value.

Compare with:
>>> n = 3.0
>>> n is 3.0
False

Here two separate compilations result in two separate values.

In general any immutable results of calculations which are the same may or
may not share the same object and this can vary according to the version of
Python or the phase of the moon. Only use 'is' when you actually care about
object identity, don't use it for a shorthand for '=='.

Christian Heimes

2/18/2008 1:12:00 PM

0

Tobiah wrote:
>>>> print float(3.0) is float(3.0)
> True
>>>> print float(3.0 * 1.0) is float(3.0)
> False
>>>>

Thumb rule: Never compare strings, numbers or tuples with "is". Only
compare an object with a singleton like a type or None. "is" is not a
comparison operator.

Christian

Erik Max Francis

2/18/2008 8:06:00 PM

0

Tobiah wrote:

>>>> print float(3.0) is float(3.0)
> True
>>>> print float(3.0 * 1.0) is float(3.0)
> False
>>>>

It's implementation dependent what values these expressions will take.

If you're trying to test equality, use `==`, not `is`.

--
Erik Max Francis && max@alcyone.com && http://www.alcyon...
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
There is nothing more incomprehensible than a wrangle among
astronomers. -- H.L. Mencken

Steven D'Aprano

2/18/2008 10:44:00 PM

0

On Mon, 18 Feb 2008 14:11:53 +0100, Christian Heimes wrote:

> Tobiah wrote:
>>>>> print float(3.0) is float(3.0)
>> True
>>>>> print float(3.0 * 1.0) is float(3.0)
>> False
>>>>>
>>>>>
> Thumb rule: Never compare strings, numbers or tuples with "is". Only
> compare an object with a singleton like a type or None. "is" is not a
> comparison operator.


I know why you're saying it, I agree with your reasons, but I wouldn't
say it that way.

Never use "is" when you want to test for EQUALITY, regardless of whether
the objects are strings, numbers, tuples, or anything else. To test for
equality, use "==".

Always use "is" when you wish to compare objects for IDENTITY, such as
testing to see whether an object IS None (as opposed to some random
object which just happens to compare equal to None).

"is" is a comparison operator: it compares identity, not equality. It is
more or less equivalent to the expression id(x) == id(y).

Except for documented singletons such as modules and None, which objects
have the same identity is platform dependent, version dependent, and even
dependent on the execution history of your code.



--
Steven

Asun Friere

2/19/2008 1:28:00 AM

0

On Feb 19, 9:44 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:

> Except for documented singletons such as modules and None, which objects
> have the same identity is platform dependent, version dependent, and even
> dependent on the execution history of your code.

The advice not to identity test strings and numbers (since they are
interred in the main implementation), or tuples, since they
potentially could be, seems sound enough. But given the nature of
immutables, is the identity of these even potentially implementation
dependant (ie. they couldn't be interred could they)? One might
conceivably want to know that a list into which one is about to stuff
something is the same (or perhaps not the same) list as that pointed
to by another name, which operation, hopefully, remains possible
across the range of potential implementations.

Asun Friere

2/19/2008 2:02:00 AM

0

On Feb 19, 12:27 pm, Asun Friere <afri...@yahoo.co.uk> wrote:
> But given the nature of immutables

I meant to write "given the nature of mutables" of course ... :/

Asun Friere

2/19/2008 2:11:00 AM

0

On Feb 19, 9:44 am, Steven D'Aprano <st...@REMOVE-THIS-
cybersource.com.au> wrote:

> Except for documented singletons such as modules and None, which objects
> have the same identity is platform dependent, version dependent, and even
> dependent on the execution history of your code.

The advice not to identity test strings and numbers (since they are
interred in the main implementation), or tuples, since they
potentially could be, seems sound enough. But given the nature of
mutables, is the identity of these even potentially implementation
dependant (ie. they couldn't be interred could they)? One might
conceivably want to know that a list into which one is about to stuff
something is the same (or perhaps not the same) list as that pointed
to by another name, which operation, hopefully, remains possible
across the range of potential implementations.

Terry Reedy

2/19/2008 2:46:00 AM

0


"Asun Friere" <afriere@yahoo.co.uk> wrote in message
news:8cafcd9e-6a61-483f-b8f3-6e7b0e5ab435@s8g2000prg.googlegroups.com...
| On Feb 19, 9:44 am, Steven D'Aprano <st...@REMOVE-THIS-
| cybersource.com.au> wrote:
|
| > Except for documented singletons such as modules and None, which
objects
| > have the same identity is platform dependent, version dependent, and
even
| > dependent on the execution history of your code.
|
| The advice not to identity test strings and numbers (since they are
| interred in the main implementation),

They may or may not be. But for almost all purposes, that is irrelevant.

| or tuples, since they potentially could be, seems sound enough.

Ditto for tuples, unless possibly when they have mutable members.

| But given the nature of
| immutables, is the identity of these even potentially implementation
| dependant (ie. they couldn't be interred could they)?

The word is 'interned', not 'interred' (buried).

| One might
| conceivably want to know that a list into which one is about to stuff
| something is the same (or perhaps not the same) list as that pointed
| to by another name, which operation, hopefully, remains possible
| across the range of potential implementations.

Lists are mutable, and identity is often important. Id(list) can be used
to debug or solve puzzling behavior.

tjr



Asun Friere

2/19/2008 4:09:00 AM

0

On Feb 19, 1:45 pm, "Terry Reedy" <tjre...@udel.edu> wrote:
> "Asun Friere" <afri...@yahoo.co.uk> wrote in message
>
> news:8cafcd9e-6a61-483f-b8f3-6e7b0e5ab435@s8g2000prg.googlegroups.com...

> | The advice not to identity test strings and numbers (since they are
> | interred in the main implementation),
>
> They may or may not be.

Obviously, and that is the problem. The behaviour will appear
inconsistent unless one is familiar with the conditions under which
they are or are not. So since the numbers and strings are interned
(under certain conditions), it is probably best not to identity test
them.

>
> Ditto for tuples, unless possibly when they have mutable members.
>

Which is the reason that they are never interned in CPython, no? So I
was wrong, the categorical avoidance of identity testing is probably
_not_ sound advice with regard to tuples.

> | But given the nature of
> | immutables, is the identity of these even potentially implementation
> | dependant (ie. they couldn't be interred could they)?
>
> The word is 'interned', not 'interred' (buried).
>

Sorry I'm a goth, so you can understand my mistake ;=

So was that a yes or no? I mean is it even possible for the identity
behaviour of mutables to vary between implementations? I can't see
how they can possibly be interned, but is there some other factor I'm
missing in regard to identity behaviour which could in fact vary
between implementations?