This has nothing to do with Spyder, this is purely a Python optimisation, as kindly explained by @Barmar.
Example 1: Line-based execution
When the values are assigned for line-execute (even if the lines are grouped when executed), the following output is provided:
>>> a = 1000.
>>> b = 1000.
>>> print(f'{id(a)=}\n{id(b)=}')
id(a)=140093502852336
id(b)=140093502851184
Different IDs.
Example 2: Function-based execution
However, when the assignments are wrapped in a function (as shown below), Python performs optimisations which basically say: "Hey, I've got a variable for that value already, so I'll just use it again."
def test():
a = 1000.
b = 1000.
print(f'{id(a)=}\n{id(b)=}')
>>> test()
id(a)=140093502851472
id(b)=140093502851472
Same IDs.
Bytecode: Function-based execution
As shown in the bytecode for the test()
function, the same ID has been assigned to the variables, due to compiler optimisations.
2 0 LOAD_CONST 1 (1000.0) # <-- Here (1)
2 STORE_FAST 0 (a)
3 4 LOAD_CONST 1 (1000.0) # <-- Here (1)
6 STORE_FAST 1 (b)
4 8 LOAD_GLOBAL 0 (print)
10 LOAD_CONST 2 ('id(a)=')
12 LOAD_GLOBAL 1 (id)
14 LOAD_FAST 0 (a)
16 CALL_FUNCTION 1
18 FORMAT_VALUE 2 (repr)
20 LOAD_CONST 3 ('\nid(b)=')
22 LOAD_GLOBAL 1 (id)
24 LOAD_FAST 1 (b)
26 CALL_FUNCTION 1
28 FORMAT_VALUE 2 (repr)
30 BUILD_STRING 4
32 CALL_FUNCTION 1
34 POP_TOP
36 LOAD_CONST 0 (None)
38 RETURN_VALUE