Interesting list Validity (True/False)

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sun May 13 00:02:30 EDT 2007


On Sat, 12 May 2007 18:43:54 -0700, mensanator at aol.com wrote:

> On May 12, 8:10?pm, Carsten Haese <cars... at uniqsys.com> wrote:
>> On Sat, 2007-05-12 at 17:55 -0700, mensana... at aol.com wrote:
>> > On May 12, 12:56?pm, Carsten Haese <cars... at uniqsys.com> wrote:
>> > > On Fri, 2007-05-11 at 14:26 -0700, mensana... at aol.com wrote:
>> > > > if arg==True:
>>
>> > > > tests the type property (whether a list is a boolean).
>>
>> > > That sounds nonsensical and incorrect. Please explain what you mean.
>>
>> > <quote>
>> > Sec 2.2.3:
>> > Objects of different types, except different numeric types and
>> > different string types, never compare equal;
>> > </quote>

I should point out that only applies to built-in types, not custom classes.


>> That doesn't explain what you mean. How does "if arg==True" test whether
>> "a list is a boolean"?
> 
>>>> type(sys.argv)
> <type 'list'>
>>>> type(True)
> <type 'bool'>


That still doesn't make sense. However, using my incredible psychic
ability to read between the lines, I think what Mensanator is trying (but
failing) to say is that "if arg==True" first tests whether arg is of type
bool, and if it is not, it knows they can't be equal. That's not actually
correct. We can check this:

>>> import dis
>>> def test(arg):
...     return arg == True
...
>>> dis.dis(test)
  2           0 LOAD_FAST                0 (arg)
              3 LOAD_GLOBAL              0 (True)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE


As you can see, there is no explicit type test. (There may or may not be
an _implicit_ type test, buried deep in the Python implementation of the
COMPARE_OP operation, but that is neither here nor there.)

Also, since bool is a subclass of int, we can do this:

>>> 1.0+0j ==  True
True





> Actually, it's this statement that's non-sensical.
> 
> <quote>
> "if arg==True" tests whether the object known as arg is equal to the
> object known as True.
> </quote>

Not at all, it makes perfect sense. X == Y always tests whether the
argument X is equal to the object Y regardless of what X and Y are.

 
> None of these four examples are "equal" to any other.

That's actually wrong, as you show further down.

 
>>>> a = 1
>>>> b = (1,)
>>>> c = [1]
>>>> d = gmpy.mpz(1)
>>>>
>>>> type(a)
> <type 'int'>
>>>> type(b)
> <type 'tuple'>
>>>> type(c)
> <type 'list'>
>>>> type(d)
> <type 'mpz'>
>>>> a==b
> False
>>>> b==c
> False
>>>> a==d
> True

See, a and d are equal.

 
> And yet a==d returns True. So why doesn't b==c
> also return True, they both have a 1 at index position 0?

Why should they return true just because the contents are the same? A bag
of shoes is not the same as a box of shoes, even if they are the same
shoes. Since both lists and tuples are containers, neither are strings or
numeric types, so the earlier rule applies: they are different types, so
they can't be equal.

gmpy.mpz(1) on the other hand, is both a numeric type and a custom class.
It is free to define equal any way that makes sense, and it treats itself
as a numeric type and therefore says that it is equal to 1, just like 1.0
and 1+0j are equal to 1.


-- 
Steven.




More information about the Python-list mailing list