470,614 Members | 1,548 Online

# conventions/requirements for 'is' vs '==', 'not vs '!=', etc

I'm wondering what is the canonical usage of the keywords 'is' and
'not' when you're writing conditionals and loops. The one I've been
following is completely arbitrary--I use the symbols '==', '!=' for
numerical comparisons and the words 'is', 'not' for everything else.

Jun 27 '08 #1
21 895
On Mon, 19 May 2008 12:39:36 -0700, destroooooy wrote:
I'm wondering what is the canonical usage of the keywords 'is' and
'not' when you're writing conditionals and loops. The one I've been
following is completely arbitrary--I use the symbols '==', '!=' for
numerical comparisons and the words 'is', 'not' for everything else.
That's wrong. Use ``==`` and ``!=`` for testing equality/inequality and
``is`` and ``is not`` for identity testing. And testing for identity is
quite rare. Rule of thumb: Use it only for known singletons like `None`.

Ciao,
Marc 'BlackJack' Rintsch
Jun 27 '08 #2
On Monday 19 May 2008 03:39:36 pm destroooooy wrote:
I'm wondering what is the canonical usage of the keywords 'is' and
'not' when you're writing conditionals and loops. The one I've been
following is completely arbitrary--I use the symbols '==', '!=' for
numerical comparisons and the words 'is', 'not' for everything else.
It's not arbitrary, and you shouldn't be using that convention.

The question is really about "equality" versus "identity". Two identical sized
cubes may be equal, but they are certainly not the same cube. The main
concept here: identity [usually] implies equality, but equality almost never
implies identity (two objects that are equal may be distinct nonetheless).

More practical example, two angles with the same measure are equal by every
mathematical concept, but opposing angles on a parallelogram are not the same
one.

Sometimes, you need to test for equality, as in "is this user input equal
to '1'?". Sometimes, you need to test for identity "is this user input
this '1' that I have here?" (note: the second answer should be 'no', unless
that by some dark magic the user manages to get that same '1' that is in your
code).

The most common use case is equality. You test for equality with == and!=.
The darker case is identity. You test for identity with "is" and "is not".
Whenever you use "is", ask yourself a question: does a negative answer makes
sense if the objects are equal?

Personally, I like to use "is" with singletons. I find it easier to type and
read "if param is None" than "if param == None", but some python developers
dislike the first one because of the "dark magic" involved in knowing that
None is a singleton.

When in doubt, test for equality. Use "is" only when you are certain that you
know the difference. Python does some optimizations that may it seem like it
is working with 'is' at first, but it really isn't:

In: a="hi"
In: b="hi"
In: a is b
Out: True <-- dark magic here, python optimized the string storage,
In: a is "h"+"i" <-- by using the same object instead of creating a new one
Out: False <-- but even that won't always work, so

In: a="a very long string, at least longer than 'hi'"
In: b="a very long string, at least longer than 'hi'"
In: a is b
Out: False <-- never, never rely on magic.

I hope I was useful.

Cheers,

--
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie
Jun 27 '08 #3
On 19 mai, 22:29, Luis Zarrabeitia <ky...@uh.cuwrote:
(snip)
The main
concept here: identity [usually] implies equality,
I really enjoyed the "usually" disclaimer !-)
Jun 27 '08 #4
Luis Zarrabeitia schrieb:
Personally, I like to use "is" with singletons. I find it easier to type and
read "if param is None" than "if param == None", but some python developers
dislike the first one because of the "dark magic" involved in knowing that
None is a singleton.
Testing for None is the only common case where you should *not* use ==
comparison. If you want to check if something is None then do "if
something is None". Easy, isn't it? :]

Look, what Python does for the various way (simplified):

"if a == None:" -"if a.__cmp__(None)"

"if a is None" -"if id(a) == id(None)"

"if a:" -"if a.__nonzero__()" / "if a.__len__()"

Christian

Jun 27 '08 #5
En Mon, 19 May 2008 17:58:48 -0300, br*****************@gmail.com
<br*****************@gmail.comescribió:
On 19 mai, 22:29, Luis Zarrabeitia <ky...@uh.cuwrote:
(snip)
>The main
concept here: identity [usually] implies equality,

I really enjoyed the "usually" disclaimer !-)
In some *rare* cases, identity does not imply equality:

pyinf = 1e300*1e300
pynan = inf-inf
pynan
-1.#IND
pynan is nan
True
pynan == nan
False

--
Gabriel Genellina

Jun 27 '08 #6
On May 20, 6:58 am, "bruno.desthuilli...@gmail.com"
<bruno.desthuilli...@gmail.comwrote:
On 19 mai, 22:29, Luis Zarrabeitia <ky...@uh.cuwrote:
(snip)
The main
concept here: identity [usually] implies equality,

I really enjoyed the "usually" disclaimer !-)
Well you have to be careful in case some smartarse comes back with a
class with something like this in it:

def __eq__ (self, other) :
if self is other : return False

%)
Jun 27 '08 #7
i am confused.

x=5
y=5

x==y -True
x is y -True

shouldnt x is y return False since they shouldnt(dont?) point to the
same place in memory, they just store an equal value?

Jun 27 '08 #8
On Mon, 19 May 2008 20:34:22 -0700 (PDT)
no**********@yahoo.se wrote:
i am confused.

x=5
y=5

x==y -True
x is y -True

shouldnt x is y return False since they shouldnt(dont?) point to the
same place in memory, they just store an equal value?
For some immutable values (such as numbers and strings), Python will have separate variables reference the same object, as an optimization. This doesn't affect anything, since the numbers are immutable anyway and a shared reference won't create any unexpected changes.

It also works with small, but not large, strings:
>>x = 'hello'
y = 'hello'
x == y
True
>>x is y
True
>>a = 'this is longer'
b = 'this is longer'
a == b
True
>>a is b
False
>>>
In the above example, Python has created only one string called 'hello' and both x and y reference it. However, 'this is longer' is two completely different objects.
Jun 27 '08 #9
no**********@yahoo.se a écrit :
i am confused.

x=5
y=5

x==y -True
x is y -True

shouldnt x is y return False since they shouldnt(dont?) point to the
same place in memory, they just store an equal value?
Python's "variable" do not "store values", they are name to object
bindings. x = 5 is a shortand for globals()['x'] = int(5), which means
"create an int instance with value 5 and bind it to the name 'x' in the
global namespace'. wrt/ the identity test yielding true, it's the result
of a CPython specific optimisation for small integer objects, that are
cached and reused. Since Python integers are immutable, they can safely
be shared. Now since it's an implementation specific thing, you should
by no mean rely on it.

Jun 27 '08 #10
Asun Friere wrote:
Well you have to be careful in case some smartarse comes back with a
class with something like this in it:

def __eq__ (self, other) :
if self is other : return False
That's pretty paranoid. :)
Who said that? (:

Uli

--
Sator Laser GmbH
GeschÃ¤ftsfÃ¼hrer: Thorsten FÃ¶cking, Amtsgericht Hamburg HR B62 932

Jun 27 '08 #11
Gabriel Genellina a écrit :
En Mon, 19 May 2008 17:58:48 -0300, br*****************@gmail.com
<br*****************@gmail.comescribió:
>On 19 mai, 22:29, Luis Zarrabeitia <ky...@uh.cuwrote:
(snip)
>>The main
concept here: identity [usually] implies equality,

I really enjoyed the "usually" disclaimer !-)

In some *rare* cases, identity does not imply equality:
Yeps. That's exactly why I enjoyed this disclaimer...

(snip nan example).
Jun 27 '08 #12
John Salerno <jo******@NOSPAMgmail.comwrote:
>>>a = 'this is longer'
b = 'this is longer'
a == b
True
>>>a is b
False
>>>>

In the above example, Python has created only one string called
'hello' and both x and y reference it. However, 'this is longer' is
two completely different objects.
That is true when run interactively, but the behaviour changes again if you
run it as a script:

C:\Temp>type t.py
a = 'this is longer'
b = 'this is longer'
print a is b

C:\Temp>t
True

In short, two equal strings may or may not be identical and any code which
makes assumptions based on observed behaviour is broken. If you want to be
able to test identity on strings safely then use the 'intern()' builtin to
get repeatable behaviour.

--
Duncan Booth http://kupuguy.blogspot.com
Jun 27 '08 #13
On May 20, 5:04*am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
John Salerno <johnj...@NOSPAMgmail.comwrote:
>>a = 'this is longer'
b = 'this is longer'
a == b
True
>>a is b
False
In the above example, Python has created only one string called
'hello' and both x and y reference it. However, 'this is longer' is
two completely different objects.

That is true when run interactively, but the behaviour changes again if you
run it as a script:

C:\Temp>type t.py
a = 'this is longer'
b = 'this is longer'
print a is b

C:\Temp>t
True

In short, two equal strings may or may not be identical and any code which
makes assumptions based on observed behaviour is broken. If you want to be
able to test identity on strings safely then use the 'intern()' builtin to
get repeatable behaviour.

--
Duncan Boothhttp://kupuguy.blogspot.com
Strictly speaking, identity is a real notion whereas equality is an
ideal (symbolic) notion. There is no such thing as real true equals.
Furthermore, there are no true real symbols. But, as puzzling as that
is:

'abc' == 'abc'
abc is abc

I argue that 'is' should never be used for primitives/literals.

a is b #good
a is { None: None } #bad
a== { None: None } #good

Just good thing I don't have check-in priveleges, right? :)
Jun 27 '08 #14
On May 20, 9:04 am, castironpi <castiro...@gmail.comwrote:
On May 20, 5:04 am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
John Salerno <johnj...@NOSPAMgmail.comwrote:
>>>a = 'this is longer'
>>>b = 'this is longer'
>>>a == b
True
>>>a is b
False
In the above example, Python has created only one string called
'hello' and both x and y reference it. However, 'this is longer' is
two completely different objects.
That is true when run interactively, but the behaviour changes again if you
run it as a script:
C:\Temp>type t.py
a = 'this is longer'
b = 'this is longer'
print a is b
C:\Temp>t
True
In short, two equal strings may or may not be identical and any code which
makes assumptions based on observed behaviour is broken. If you want to be
able to test identity on strings safely then use the 'intern()' builtin to
get repeatable behaviour.
--
Duncan Boothhttp://kupuguy.blogspot.com

There is no such thing as real true equals.
That's quite some dark deep philosophy. Fortunately, computers are not
as complicated as real life. I would argue that, programatically,
there *is* such thing as "real true equals". I would also argue that
that view is most certainly not shared by everyone.
Jun 27 '08 #15
"Duncan Booth" <du**********@invalid.invalidwrote in message
news:Xn*************************@127.0.0.1...
That is true when run interactively, but the behaviour changes again if
you
run it as a script:
Yeah, I forgot to mention that you shouldn't rely on this behavior. :)
Jun 27 '08 #16

"Duncan Booth" <du**********@invalid.invalidwrote in message
news:Xn*************************@127.0.0.1...
| In short, two equal strings may or may not be identical and any code
which
| makes assumptions based on observed behaviour is broken. If you want to
be
| able to test identity on strings safely then use the 'intern()' builtin
to
| get repeatable behaviour.

Intern() is gone in 3.0

Jun 27 '08 #17
On May 20, 12:09 pm, "Terry Reedy" <tjre...@udel.eduwrote:
Intern() is gone in 3.0
But not gone far:
>>import sys
sys.intern
<built-in function intern>
Jun 27 '08 #18
On May 20, 11:49*am, s0s...@gmail.com wrote:
On May 20, 9:04 am, castironpi <castiro...@gmail.comwrote:

On May 20, 5:04 am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
John Salerno <johnj...@NOSPAMgmail.comwrote:
>>a = 'this is longer'
>>b = 'this is longer'
>>a == b
True
>>a is b
False
In the above example, Python has created only one string called
'hello' and both x and y reference it. However, 'this is longer' is
two completely different objects.
That is true when run interactively, but the behaviour changes again if you
run it as a script:
C:\Temp>type t.py
a = 'this is longer'
b = 'this is longer'
print a is b
C:\Temp>t
True
In short, two equal strings may or may not be identical and any code which
makes assumptions based on observed behaviour is broken. If you want to be
able to test identity on strings safely then use the 'intern()' builtin to
get repeatable behaviour.
--
Duncan Boothhttp://kupuguy.blogspot.com
There is no such thing as real true equals.

That's quite some dark deep philosophy. Fortunately, computers are not
as complicated as real life. I would argue that, programatically,
there *is* such thing as "real true equals". I would also argue that
that view is most certainly not shared by everyone.- Hide quoted text -

- Show quoted text -
Mean as it sounds, bits are pigeonholes: 5+V or 0. As such, computers
are able to simulate numerical identity, but, don't forget, all your
inputs are discretized (pigeonholed).

Symbolic (mathematical) identity (equality) is defined as a reflexive,
symmetric, transitive relation, and partitions its domain into
equivalence classes (membership in which is binary). Symbols are
outside of cause.

Ma: Symbolic identity is a mathematical relation
Mb: Symbols are acausal
m: Matter is causal
C: Symbolic identity is not defined on matter.

Further, conclude computers are symbolic only. Now, what can a hoard
of people do with some symbols?

But, I defer on the practical sense.
Jun 27 '08 #19
On May 20, 10:42*am, John Salerno <johnj...@NOSPAMgmail.comwrote:
On Mon, 19 May 2008 20:34:22 -0700 (PDT)

notnorweg...@yahoo.se wrote:
i am confused.
x=5
y=5
x==y -True
x is y -True
shouldnt x is y return False since they shouldnt(dont?) point to the
same place in memory, they just store an equal value?

For some immutable values (such as numbers and strings), Python will have separate variables reference the same object, as an optimization. This doesn't affect anything, since the numbers are immutable anyway and a shared reference won't create any unexpected changes.

It also works with small, but not large, strings:
>x = 'hello'
y = 'hello'
x == y
True
>x is y
True
>a = 'this is longer'
b = 'this is longer'
a == b
True
>a is b
False

In the above example, Python has created only one string called 'hello' and both x and y reference it. However, 'this is longer' is two completely different objects.
But the rule of thumb is: Don't rely on this optimization, it's an
implementation detail.
Jun 27 '08 #20
On May 20, 2:39*am, destroooooy <destrooo...@gmail.comwrote:
I'm wondering what is the canonical usage of the keywords 'is' and
'not' when you're writing conditionals and loops. The one I've been
following is completely arbitrary--I use the symbols '==', '!=' for
numerical comparisons and the words 'is', 'not' for everything else.

If we're talking in English, it would be like this:

There is a person with a black hair called A
There is another person with a black hair called B
A has a nickname C

All of these statements are true:
A.haircolor == B.haircolor
A is C

but this is NOT true:
A is B # is False

and this is debatable:
A == B

whether A is similar enough to B so that they can be said to be equal
is debatable and depends on the purpose of the comparison (which is
why equality comparison is overridable while identity comparison is
not).
Jun 27 '08 #21
>Ma: Symbolic identity is a mathematical relation
>Mb: Symbols are acausal
m: Matter is causal
C: Symbolic identity is not defined on matter.
What is defined on matter then? You're saying all symbolism is not defined
on matter. Much of our thinking about the world itself is symbolic. How do
we 'define on matter' without thinking about it? Definition is another
symbolic thinking thing we do. What does it mean to 'define on matter'? If
you were to paint symbol/matter like the mind/body problem interpreted on
dualism (not to beg the question, but just to say if you're saying they're
different substances) then some people would ask, how does one thing
interact with the other? You could say that symbols don't exist and
inferring symbols is just a way of thinking of the world, but since we think
in symbols, thinking becomes something that doesn't exist and is inferred
from a way of thinking about the world, which doesn't exist and is inferred
from a way of thinking about the world, etc. I don't think you can say that
thought-symbolism is a different question from mathematical symbolism
because Aristotle inferred "a is a" directly from the way we think about the
world. cf:
>>>a is a
True

Perhaps symbols and symbolic identity are defined as algorithms which happen
in the real world to come to a conclusion. It raises the question of how
causal an algorithm is. But if you call an algorithm 'a way of doing
something' then it's much more down-to-Earth. But it raises the question
of how we define the boundaries of whether doing something is 'doing that
thing' (since an algorithm is strictly formal and mathematically
deterministic), given that you never step in the same river twice, since you
then have to define the boundaries of determining whether doing something
falls within the boundaries or not, ad infinitum.

I don't have a conclusion. Suffice it to say it obviously works out
somehow. I'm just wondering about what 'defined on matter' means.

Jun 27 '08 #22

### This discussion thread is closed

Replies have been disabled for this discussion.