3

I saw this question here and now I'm curious. How does the is operator behave in python in comparison to the === sign in JS?

Community
  • 1
  • 1
Athena
  • 3,200
  • 3
  • 27
  • 35
  • 1
    How is that the same question? It makes no mention of JS anywhere, and while I know the difference between `is` and ==, I want to know how it relates to `===`. – Athena Jun 29 '16 at 19:33

3 Answers3

7

No, they are not the same. is in Python checks if two objects have the same id in Python, ie. they are the same, even in memory. Something you can do to check is this:

>>> a='foo'
>>> a is 'foo'
True
>>> id(a)
44434088
>>> id('foo')
44434088
>>> a=[1]
>>> a is [1]
False
>>> id(a)
45789792
>>> id([1])
4469824
Brian
  • 1,659
  • 12
  • 17
  • 3
    FWIW, I think that `id(a)` and `id('foo')` being the same is something that frequently confuses people when they're trying to understand identity in python. The fact that `'foo'` is interned by the interpreter is not really an entry level python topic :-) – mgilson Jun 29 '16 at 19:33
  • So, is it like a hash of the object? How are `id` values assigned? – Athena Jun 29 '16 at 19:35
  • @Ares As in `is` will only return true if it's the comparing the exact same object in memory. – Spencer Wieczorek Jun 29 '16 at 19:35
  • Yeah, but `'foo'` and `a` are clearly *not* the same object, so why does their comparison return true? – Athena Jun 29 '16 at 19:36
  • @mgilson, I learned that in the textbook that I learned Python from. It *should* be something people learn, but I do concede that it could be considered a little advanced. – Brian Jun 29 '16 at 19:36
  • You should also add that the `===` checks if two variables are the same in value and type in JS. – andybeli Jun 29 '16 at 19:37
  • @Ares -- The id numbers are assigned differently for different python implementations. Cpython (the reference implementation that most people have) uses the object's memory address. – mgilson Jun 29 '16 at 19:38
  • @andybeli No they should not, that would be noise. – Spencer Wieczorek Jun 29 '16 at 19:38
  • @mgilson which brings me back to my other point of confusion, if they're by memory address, then why did the check on the string literal return true? They shouldn't have the same memory address, right? – Athena Jun 29 '16 at 19:39
  • @SpencerWieczorek it should not what? Could you be more specific... My statement is correct. – andybeli Jun 29 '16 at 19:39
  • @andybeli The OP already knows that, they even give a link to the question/answer which states that. There isn't a reason to include it. – Spencer Wieczorek Jun 29 '16 at 19:40
  • @Ares -- This is what I was pointing out as confusing by my initial comment. Python holds a cache of strings (as an optimization). Frequently (always?) when you reference a string literal, python will look for it in the cache of interned strings and give you the same one that was previously defined. – mgilson Jun 29 '16 at 19:41
  • @Ares, see this discussion about the string literals http://stackoverflow.com/questions/24245324/about-the-changing-id-of-a-python-immutable-string – Brian Jun 29 '16 at 19:42
  • That `is` tricky... That seems like undesired behavior. Without being able to tell if the string has been cached, there's no way to tell if the `is` operation will actually return true, right? – Athena Jun 29 '16 at 19:43
  • 1
    @Ares -- Nope, there isn't a good way to tell what `is` on two strings which are equivalent will return. With that said, it's a pretty niche use-case. Generally `is` comparisons aren't done on strings (or small integers which are the other common objects that can exhibit this strange behavior). Equality is generally good enough. If you really need to do reference checking, it's more common to do that on named sentinel objects (`FOO = object()` rather than `FOO = 'foo'`). – mgilson Jun 29 '16 at 19:46
2

In Javascript, the == operator will do implicit type conversion when comparing for equality so, for instance, [] == "" will return true. The === operator is used to check equality without type conversion ([] === "" returns false.)

In Python, the is keyword checks reference equality. So x is y will only return true if x and y both point to the same object in memory. For instance:

x = [1, 2, 3]
y = [1, 2, 3]
z = x
x is y # False
x is z # True

Some gotchas that may result from this are the suggested check for null, x is None. None always points to the same space in memory, so you can be assured that x is None will always return True if x has a None value (and False otherwise).

You may also come across some quirks, like the following:

x = 1
y = 1
x is y # True

The above is a result of a non-standard behaviour in CPython (the Python interpreter you're probably using) where small integers are all assigned to specific objects when the program starts up. You can check that this doesn't work for larger numbers:

x = 1000
y = 1000
x is y # False

Unless you're checking for None or if you specifically want to make sure two variables are pointing to the same location in memory, you should use == instead of is.

Blue_vision
  • 164
  • 6
1

No. is in Python is seemingly much stricter than === in JS.

In JS:

For value types (numbers): a === b returns true if a and b have the same value and are of the same type

For reference types: a === b returns true if a and b reference the exact same object

For strings: a === b returns true if a and b are both strings and contain the exact same characters


In Python:

Without contradiction, except id(obj1) is the same as id(obj2), both objects are not identical, and obj1 is obj2 will evaluate to False.

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139