Why is the behavior different between the two?
When you create a new value in CPython, you essentially create an entire new object containing that value. For small integer values (from -5 to 256), CPython decides to reuse old objects you have created earlier. This is called interning and it happens for performance reasons – it is considered cheaper to keep around old objects instead of creating new ones.
Am I correct to generalize this behavior to all ints and all longs?
No. As I said, it only happens for small ints. It also happens for short strings. (Where short means less than 7 characters.) Do not rely on this. It is only there for performance reasons, and your program shouldn't depend on the interning of values.
Is this CPython specific?
Not at all. Although the specifics may vary, many other platforms do interning. Notable in this aspect is the JVM, since in Java, the ==
operator means the same thing as the Python is
operator. People learning Java are doing stuff like
String name1 = "John";
String name2 = "John";
if (name1 == name2) {
System.out.println("They have the same name!");
}
which of course is a bad habit, because if the names were longer, they would be in different objects and the comparison would be false, just like in Python if you would use the is
operator.