Seemingly odd 'is' comparison.

Boris Borcic bborcic at gmail.com
Tue Feb 19 08:47:06 EST 2008


Arnaud Delobelle wrote:
> On Feb 13, 10:19 pm, Tobiah <t... at tobiah.org> wrote:
>>>>> print float(3.0) is float(3.0)
>> True
>>>>> print float(3.0 * 1.0) is float(3.0)
>> False
> 
> [You don't need to wrap your floats in float()]
> 
>>>> def f():
> ...     return 3.0 is 3.0, 3.0*1.0 is 3.0
> ...
>>>> f()
> (True, False)
>>>> import dis
>>>> dis.dis(f)
>   2           0 LOAD_CONST               1 (3.0)
>               3 LOAD_CONST               1 (3.0)
>               6 COMPARE_OP               8 (is)
>               9 LOAD_CONST               3 (3.0)
>              12 LOAD_CONST               1 (3.0)
>              15 COMPARE_OP               8 (is)
>              18 BUILD_TUPLE              2
>              21 RETURN_VALUE
> 
> As you can see when "3.0 is 3.0" is evaluated the same float object is
> put on the stack twice so the 'is' comparison is True (LOAD_CONST 1 /
> LOAD_CONST 1 / COMPARE_OP 8).
> 
> Whereas when "3.0*1.0 is 3.0" is evaluated, *two* different float
> objects are put on the stack and compared (LOAD_CONST 3 / LOAD_CONST
> 1 / COMPARE_OP 8).  Therefore the result is False.

Looks good, but doesn't pass the sanity check ;) Consider

 >>> def f():
	return 3 is 3, 3*1 is 3

 >>> import dis
 >>> dis.dis(f)
   2           0 LOAD_CONST               1 (3)
               3 LOAD_CONST               1 (3)
               6 COMPARE_OP               8 (is)
               9 LOAD_CONST               3 (3)
              12 LOAD_CONST               1 (3)
              15 COMPARE_OP               8 (is)
              18 BUILD_TUPLE              2
              21 RETURN_VALUE
 >>> f()
(True, True)

Cheers, BB




More information about the Python-list mailing list