negative numbers are not equal...

A

ariel ledesma

hello guys

i just ran into this when comparing negative numbers, they start
returning False from -6 down, but only when comparing with 'is'
True

i read that 'is' compares if they are really the same object, but i
don't that's it because then why does -5 return True?
of course i could only use == to compare, but still, what am i missing here?
thanks in advance

ariel
 
J

Josh English

hello guys

i just ran into this when comparing negative numbers, they start
returning False from -6 down, but only when comparing with 'is'

 >>> m = -5
 >>> a = -5
 >>> m is a
True
 >>> m = -6
 >>> a = -6
 >>> m is a
False
 >>> m == a
True

i read that 'is' compares if they are really the same object, but i
don't that's it because then why does -5 return True?
of course i could only use == to compare, but still, what am i missing here?
thanks in advance

ariel

strange, I get the same thing.

From the docs
The operators is and is not test for object identity: x is y is true
if and only if x and y are the same object. x is not y yields the
inverse truth value.

so:
a = b = -6
a is b
True

It is odd behaviour, but I would stick to '==' when comparing numeric
values
 
D

Dan Lenski

hello guys

i just ran into this when comparing negative numbers, they start
returning False from -6 down, but only when comparing with 'is'

True

i read that 'is' compares if they are really the same object, but i
don't that's it because then why does -5 return True? of course i could
only use == to compare, but still, what am i missing here? thanks in
advance

They also return False for positive numbers > 256. Try this:
>>> print [x for x in range(-10,260) if x is not x+1-1]
[-10, -9, -8, -7, -6, 257, 258, 259]

There is a good explanation for this: the "is" operator checks for object
identity, not equality. Basically "a is m" asks, does the variable name
"a" reference the same memory location as the variable name "m"?

For integers in the range of -5<=x<=256, Python pre-caches all of these
values, and whenever a variable takes on one of those values, it uses the
cached value. This is an optimization: it prevents the need to allocate
a new Python object for these very very common small integer values.

For integer literals outside this range, a new Python object gets created
when they are assigned to variables, so a=500 followed by m=500 will
create new objects.

The "is" operator just shows the effect of this caching. It's
unimportant for real code since you never care whether two numeric
variables refer to the same object (only important for complex data
structures where their storage may overlap)... only whether they are
equal or not.

Dan Lenski

(PS- The small integer pre-caching is described somewhere in the C API
docs.)
 
B

Bruno Desthuilliers

castironpi a écrit :
(snip)
It would be nice to put together a really canonical case of the use of
the 'is' comparison. FTSOA for the sake of argument, when do you use
it?

When I want to test objects identity. An idenity test is an identity
test is an identity test is an....
Why is it even in the language?

Because there's a need for it.
 
C

castironpi

hello guys
i just ran into this when comparing negative numbers, they start
returning False from -6 down, but only when comparing with 'is'
 >>> m = -5
 >>> a = -5
 >>> m is a
True
 >>> m = -6
 >>> a = -6
 >>> m is a
False
 >>> m == a
True
i read that 'is' compares if they are really the same object, but i
don't that's it because then why does -5 return True? of course i could
only use == to compare, but still, what am i missing here? thanks in
advance

They also return False for positive numbers > 256.  Try this:
 >>> print [x for x in range(-10,260) if x is not x+1-1]
[-10, -9, -8, -7, -6, 257, 258, 259]

There is a good explanation for this: the "is" operator checks for object
identity, not equality.  Basically "a is m" asks, does the variable name
"a" reference the same memory location as the variable name "m"?

For integers in the range of -5<=x<=256, Python pre-caches all of these
values, and whenever a variable takes on one of those values, it uses the
cached value.  This is an optimization: it prevents the need to allocate
a new Python object for these very very common small integer values.

For integer literals outside this range, a new Python object gets created
when they are assigned to variables, so a=500 followed by m=500 will
create new objects.

The "is" operator just shows the effect of this caching.  It's
unimportant for real code since you never care whether two numeric
variables refer to the same object (only important for complex data
structures where their storage may overlap)... only whether they are
equal or not.

Dan Lenski

(PS- The small integer pre-caching is described somewhere in the C API
docs.)

It would be nice to put together a really canonical case of the use of
the 'is' comparison. FTSOA for the sake of argument, when do you use
it? Why is it even in the language?

If you're iterating over a list,

flagA= object()
flagB= object()
flagC= -10
listA= [ objectA, objectB, flagA, objectC, flagB, -10, objectD ]
flags= [ listA, listB, listC ]
for iA in listA:
for flag in flags:
if iA is flag:
handle( iA )

This case actually misses handleC(). The solution is that the
function that is returning '-10' cannot return -10, it has to return
flagC. This can cause difficulties in cases when you're doing
operations on flags. Worse, if flagC is nested somewhere, say
moduleA.classB.flagC, you still have to work with that, not its value.
 
F

Fredrik Lundh

castironpi said:
This case actually misses handleC(). The solution is that the
function that is returning '-10' cannot return -10, it has to return
flagC. This can cause difficulties in cases when you're doing
operations on flags. Worse, if flagC is nested somewhere, say
moduleA.classB.flagC, you still have to work with that, not its value.

do you *ever* make any sense at all?

</F>
 
B

Bruno Desthuilliers

Terry Reedy a écrit :
Excellent example. There are three

make it four.
uses for 'is'.
1. Minor optimization of comparison with None, True, False.

Warning (to any python newbie reading this): x is True is *very*
different from x == True. IOW ;: don't use 'is' with True and False
unless you know *exactly* what you're doing.
2. Testing the implementation: 'a=1;b=1;a is b' *should* be True, while
'a=257;b=257;a is b' *should* be False. The CPython test suite has
tests like this.
3. Comparision of user class objects where identify is important.
Objects representing people is certainly such a case ;-).

4. Anywhere you want to test identity.
 
M

Mel

castironpi said:
It would be nice to put together a really canonical case of the use of
the 'is' comparison. FTSOA for the sake of argument, when do you use
it? Why is it even in the language?

My poster child use case is in a MUDD game. For instance, the player
represented by `this_player` has picked up the yoghurt. We notify the
other players using code that boils down to:

for person in this_room.inhabitants:
if person is not this_player:
person.notify ('%s has picked up the %s.'
% (this_player.name, 'yoghurt'))

The `is` test avoids telling this_player something he already knows.
Perhaps the code could be written to make an equality test work, but then
again, perhaps the game could have a much more interesting use for equality
between persons.

Mel.
 
T

Terry Reedy

Mel said:
My poster child use case is in a MUDD game. For instance, the player
represented by `this_player` has picked up the yoghurt. We notify the
other players using code that boils down to:

for person in this_room.inhabitants:
if person is not this_player:
person.notify ('%s has picked up the %s.'
% (this_player.name, 'yoghurt'))

The `is` test avoids telling this_player something he already knows.
Perhaps the code could be written to make an equality test work, but then
again, perhaps the game could have a much more interesting use for equality
between persons.

Excellent example. There are three uses for 'is'.
1. Minor optimization of comparison with None, True, False.
2. Testing the implementation: 'a=1;b=1;a is b' *should* be True, while
'a=257;b=257;a is b' *should* be False. The CPython test suite has
tests like this.
3. Comparision of user class objects where identify is important.
Objects representing people is certainly such a case ;-).

tjr
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top