In other words:
x = "foo"
y = "foo"
x == y and x is y
Both strings point to the same exact memory. Hence, 'is' works.
But it isn't always true: x = "foo"
y = f"{x} "[:-1] # get everything but the space
x == y # True
y is x # FalseEvery JVM language that came after Java reverses this. Here, "is" simply is too nice. Should've named it something nobody will accidentally use.
In python it’s common due to `None`, which you really want to check by identity. Other placeholders as well. This is such a major use case that in 3.9 `is` was moved out of the generic `compare_op` instruction and into its own.
And because __eq__ can be overridden, aside from being noticeably slower `x == None` is not truly reliable.
Rule of thumb is use == for everything except True/False/None. Once you get going with python you'll learn the meaning of is eventually, and you'll still barely ever need to use it.
Small integers, as they are kept around, probably are as well (5 is (2+3) works).
I think what gets dropped during the conversation is, that we've been living with Java doing it this way (is being == and == being .equals) for decades and nobody really complains.
2. 1 == True and 0 == False, as booleans subclass the int type. On the other hand is distingushes between 1 and True, and 0 and False respectively.
Except the string comparison with "is". It's confusing, because there are no errors, and when I try them in the Python REPL, it "works". The code is logical, I tested the example and it works...
...except when it doesn't, but if I'm just a naive beginner, I'll need to learn the hard way that it doesn't always work
For this reason, I'd be okay with saying that "it" for strings is a WTF of the language.