Interesting list Validity (True/False)

mensanator at aol.com mensanator at aol.com
Sun May 13 00:50:12 EDT 2007


On May 12, 11:02�pm, Steven D'Aprano
<s... at REMOVE.THIS.cybersource.com.au> wrote:
> On Sat, 12 May 2007 18:43:54 -0700, mensana... 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.

Except for the exceptions, that's why the statement is wrong.

>
> > None of these four examples are "equal" to any other.
>
> That's actually wrong, as you show further down.

No, it's not, as I 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.

No, they are not "equal". Ints and mpzs should NEVER
be used together in loops, even though it's legal. The ints
ALWAYS have to be coerced to mpzs to perform arithmetic
and this takes time...LOTS of it. The absolute stupidest
thing you can do (assuming n is an mpz) is:

while n >1:
    if n % 2 == 0:
        n = n/2
    else:
        n = 3*n + 1

You should ALWAYS do:

ZED = gmpy.mpz(0)
ONE = gmpy.mpz(1)
TWO = gmpy.mpz(2)
TWE = gmpy.mpz(3)

while n >ONE:
    if n % TWO == ZED:
        n = n/TWO
    else:
        n = TWE*n + ONE

This way, no coercion is performed.

>
> > 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?

Why should the int 1 return True when compared to mpz(1)?

a = [1]
b = [1]

returns True for a==b? After all, it returns false if b is [2],
so it looks at the content in this case. So for numerics,
it's the value that matters, not the type. And this creates
a false sense of "equality" when a==d returns True.

> A bag
> of shoes is not the same as a box of shoes, even if they are the same
> shoes.

Exactly. For the very reason I show above. The fact that the int
has the same shoes as the mpz doesn't mean the int should be
used, it has to be coerced.

> 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.

But you can't trust a==d returning True to mean a and d are
"equal". To say the comparison means the two objects are
equal is misleading, in other words, wrong. It only takes one
turd to spoil the whole punchbowl.

>
> 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.

They are equal in the mathematical sense, but not otherwise.
And to think that makes no difference is to be naive.

>
> --
> Steven




More information about the Python-list mailing list