On Fri, Jul 7, 2017 at 5:29 PM, Dan Wissme <wis...@free.fr> wrote: > Strange behavior in Python 3.6.0 >>>> i = 3000 >>>> j = 3000 >>>> i is j > False >>>> n = 4000 ; m = 4000 ; n is m > True
Firstly, remember that immutables are allowed, but not required, to be shared. So this kind of "strange behaviour" is completely fine - and furthermore, can come and go at any time. What you're seeing here is an artifact of the interactive interpreter. Each statement or block that you enter gets compiled and executed on its own. When you do the last block, the compiler looks at the whole thing, and produces this code: >>> c = compile("n = 4000 ; m = 4000 ; n is m", "<stdin>", "single") >>> c.co_consts (4000, None) >>> dis.dis(c) 1 0 LOAD_CONST 0 (4000) 2 STORE_NAME 0 (n) 4 LOAD_CONST 0 (4000) 6 STORE_NAME 1 (m) 8 LOAD_NAME 0 (n) 10 LOAD_NAME 1 (m) 12 COMPARE_OP 8 (is) 14 PRINT_EXPR 16 LOAD_CONST 1 (None) 18 RETURN_VALUE The print and return at the end are how the REPL works. The rest is your code. The compiler noticed that it needed to load the constant integer 4000 twice, so it put it into the co_consts collection once and used the same integer object each time. Armed with that information, it should be easy to see why your 3000 example returned False. Each of the assignments was compiled separately, and the compiler didn't look at previous compilations to reuse an integer. Thus the two are separate objects. The compiler COULD, if it felt like it, reuse that; conversely, a naive and inefficient compiler is welcome to generate brand new integers for n and m. Actually, I believe a compliant Python interpreter is welcome to not store integer objects in memory at all, as long as it can guarantee the correct identity semantics (eg the 'is' and 'is not' operators on integers would be defined on value, and id(x) would return x*2+1 for ints and even numbers for other objects), although I don't know of any implementations that do this. ChrisA -- https://mail.python.org/mailman/listinfo/python-list