checking if a list is empty

H

Hans Georg Schaathun

> Revolutionary indeed, so why don't we exploit the revolution
: > and write the programs to be as accessible as possible?
:
: Where do you draw the line, though?

I said that, "as possible". You draw it at the limit of possibility.

: No decorators, as they're not intuitively obvious? No custom
: descriptors, as that requires a deeper knowledge of Python internals
: that utter ignorance allows?

When they help clarify or simplify the code, they are good.
When they do nothing of the sort, they aren't.

: Both of those aspects alone seem far more complex and advanced than
: treating empty collections as False.

Probably, but they also seem far more useful.
 
G

Gregory Ewing

That's just the default treatment for unrelated types that don't
know anything about each other.

I would guess that the list's == method is asking "Is the
other object a list?", and since a subclass of list is also
a list, it's happy and goes on to compare the elements.
 
H

Hans Georg Schaathun

Roy Smith wrote:
: >>If both are numbers, they are converted to a common type. Otherwise,
: >>objects of different types always compare unequal

Actually, I did not.
:-- hg
 
R

Roy Smith

Gregory Ewing said:
That's just the default treatment for unrelated types that don't
know anything about each other.

I would guess that the list's == method is asking "Is the
other object a list?", and since a subclass of list is also
a list, it's happy and goes on to compare the elements.

Well, that explains what's happening, but the behavior still doesn't
match the docs. Is this a bug or are the docs wrong?
 
T

Terry Reedy

I conclude that li == [] should have returned False. Either I'm not
understanding things correctly, or this is a bug.

The doc is wrong (and not only on this). I am working on a report with
suggested fixes. Will post number when finish.
 
S

Steven D'Aprano

Well, that explains what's happening, but the behavior still doesn't
match the docs. Is this a bug or are the docs wrong?


The docs are incomplete.

You are missing two facts:

* The docs you are quoting refer only to built-in types. That it doesn't
make so clear is a documentation bug.

* Talking about "different" and "same" types is ambiguous. It depends on
how you compare types:

type(a) is type(b)

isinstance(a, type(b))

You are reading the docs as if the first comparison is the way to do it,
but the second is usually preferred.

Any time you read something about "the same type", you should mentally
add "(or an instance of a sub-class)" to it, unless explicitly told
different. Whether it is better to add that parenthetical comment every
time it is needed, or to assume that the read knows enough about object-
oriented programming to assume it, is an open question.

Me personally, I think it's part of the mental landscape that can be
assumed, like C docs might state "dereference the pointer" without adding
"(unless it is a nul pointer)" *every single time*.
 
R

rusi

Mathematics has existed for millenia.
Hindu-arabic numerals (base-10 numbers) have been known for about one
millennium
The boolean domain is only a 100 years old.
Unsurprisingly it is not quite 'first-class' yet: See
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1070.html
[Lifted from http://c2.com/cgi/wiki?EqualVsTrueFalse ]

----------------------------
"In retrospect, one might be tempted to regard the introduction of
something as simple as the boolean domain as a minor invention, but I
think that that would be a grave mistake: it is a great invention
because, being so simple, it is such a powerful simplifier. It is of
the same level as the introduction of natural numbers, which enabled
us to add 3 to 5, regardless of whether we are adding apples or
pears."

"George Boole made a radical invention, so radical, in fact, that now,
more than a century later, the scientific community has not absorbed
it yet. (To stay with the metaphor: officially, boolean expressions
may have reached the status of first-class citizens, in practice —
because old habits and prejudices die hard— they are still the victims
of discrimination.) Let me give you a few examples."

"In the programming language FORTRAN, as conceived a century after
Boole published his invention, boolean expressions are allowed, but
there are no boolean variables! Their introduction into programming
had to wait until the design of ALGOL 60."

------------------------
So, M Harris problem is that python could almost be a language for the
'masses' (whatever that might mean) were it not for warts like "l not
is empty" is shorten-able to just "l"

Dijkstra's problem (paraphrased) is that python, by choosing the
FORTRAN alternative of having a non-first-class boolean type, hinders
scientific/mathematical thinking/progress.

I tend to agree with Dijkstra's view that the boolean type should be
given more respect
except for the small fact that the computer's ALU is based on the
logic-arithmetic pun:
half-adder = xor
(half)-carry = and
 
C

Chris Rebert

The boolean domain is only a 100 years old.
Unsurprisingly it is not quite 'first-class' yet: See

It is nowadays. Every halfway-mainstream language I can think of has
an explicit boolean datatype. Heck, as of C99, even C has one now. I
conjecture the only languages still lacking one are exotic
niche/fringe languages. I would be interested to see a counterexample.
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1070.html
[Lifted from http://c2.com/cgi/wiki?EqualVsTrueFalse ]

----------------------------
"In retrospect, one might be tempted to regard the introduction of
something as simple as the boolean domain as a minor invention, but I
think that that would be a grave mistake: it is a great invention
because, being so simple, it is such a powerful simplifier. It is of
the same level as the introduction of natural numbers, which enabled
us to add 3 to 5, regardless of whether we are adding apples or
pears."

"George Boole made a radical invention, so radical, in fact, that now,
more than a century later, the scientific community has not absorbed
it yet. (To stay with the metaphor: officially, boolean expressions
may have reached the status of first-class citizens, in practice —
because old habits and prejudices die hard— they are still the victims
of discrimination.) Let me give you a few examples."

"In the programming language FORTRAN, as conceived a century after
Boole published his invention, boolean expressions are allowed, but
there are no boolean variables! Their introduction into programming
had to wait until the design of ALGOL 60."

One language's wart is another language's idiom. And I think the
irrational hate towards syntactically-significant indentation is by
far a much larger barrier to "mass" adoption of Python; C++ has some
features that are at least (if not more) subtle/unobvious than
Python's __bool__(), yet it still enjoys "mass" use.
Dijkstra's problem (paraphrased) is that python, by choosing the
FORTRAN alternative of having a non-first-class boolean type, hinders
scientific/mathematical thinking/progress.

Python has *not* chosen the Fortran alternative; *it has a first-class
Boolean type*, namely bool. This line of argument thus fails.
The fact that other types are implicitly coercible to bools doesn't
make `bool` itself any less first-class.

It is also ironic that one of the projects that exploits Python's
flexible typing regarding normally-Boolean operators is a scientific
one (NumPy).

Cheers,
Chris
 
R

rusi

It is nowadays. Every halfway-mainstream language I can think of has
an explicit boolean datatype.

I guess you did not quite see my 'quite' -- which itself is a
summarization of Dijkstra's "officially" vs "in practice" ? [Heres the
quote]

----------------------------
"In retrospect, one might be tempted to regard the introduction of
something as simple as the boolean domain as a minor invention, but I
think that that would be a grave mistake: it is a great invention
because, being so simple, it is such a powerful simplifier. It is of
the same level as the introduction of natural numbers, which enabled
us to add 3 to 5, regardless of whether we are adding apples or
pears."
"George Boole made a radical invention, so radical, in fact, that now,
more than a century later, the scientific community has not absorbed
it yet. (To stay with the metaphor: officially, boolean expressions
may have reached the status of first-class citizens, in practice —
because old habits and prejudices die hard— they are still the victims
of discrimination.) Let me give you a few examples."
"In the programming language FORTRAN, as conceived a century after
Boole published his invention, boolean expressions are allowed, but
there are no boolean variables! Their introduction into programming
had to wait until the design of ALGOL 60."


As an analogy, in Perl, a list can get coerced to its length "... when
in scalar context.." or something like that. Most programmers from
the static-typechecked-languages camp would balk at that laissez faire
attitude. Likewise Harris is pointing out that noob python
programmers may feel a bit unnerved by non-boolean types unexpectedly
showing 'boolean-ness.' Maybe we are just more in noob category and
we've not got the zen of python?? Dunno...
 
G

Gregory Ewing

rusi said:
Dijkstra's problem (paraphrased) is that python, by choosing the
FORTRAN alternative of having a non-first-class boolean type, hinders
scientific/mathematical thinking/progress.

Python doesn't have the flaw that Dijkstra was talking about.
Fortran's flaw wasn't so much the lack of a boolean type, but
that you couldn't assign the result of a logical expression to
a variable. Python has always been able to do that, even before
it had a distinct boolean type.
 
S

Steven D'Aprano

Mathematics has existed for millenia. Hindu-arabic numerals (base-10
numbers) have been known for about one millennium
The boolean domain is only a 100 years old. Unsurprisingly it is not
quite 'first-class' yet: See
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1070.html
[Lifted from http://c2.com/cgi/wiki?EqualVsTrueFalse ]

Th money-quote as regards using arbitrary objects in truth tests:

All this changed with the introduction of the two-element
boolean domain {true, false} which provides the vocabulary
needed to assign values to boolean expressions: 3<4 is a
way for writing true, 3>4 is a way for writing false,
whereas the value of x>0 depends on the value of x ...
[end quote]


In Python, [1, 2, 3] is another way of writing true, and [] is another
way of writing false. Similarly with any other arbitrary objects. The
only things that bools True and False are good for are:

* giving functions a canonical way of spelling true/false when they want
to emit a Boolean value;

* giving documentation writers a canonical way of spelling true/false
when they want to discuss passing a Boolean value.

Other than those conveniences, there's nothing you can do with True and
False in Python that you can't do with any other set of objects.
 
R

rusi

Mathematics has existed for millenia. Hindu-arabic numerals (base-10
numbers) have been known for about one millennium
The boolean domain is only a 100 years old. Unsurprisingly it is not
quite 'first-class' yet: See
http://www.cs.utexas.edu/users/EWD/transcriptions/EWD10xx/EWD1070.html
[Lifted fromhttp://c2.com/cgi/wiki?EqualVsTrueFalse]

Th money-quote as regards using arbitrary objects in truth tests:

   
    All this changed with the introduction of the two-element
    boolean domain {true, false} which provides the vocabulary
    needed to assign values to boolean expressions: 3<4 is a
    way for writing true, 3>4 is a way for writing false,
    whereas the value of x>0 depends on the value of x ...
    [end quote]

In Python, [1, 2, 3] is another way of writing true, and [] is another
way of writing false. Similarly with any other arbitrary objects.

Well so is [1,2] another way of writing True

And then we get the interesting result that
(True = True) is False
 
H

Hans Mulder

What if it's not a list but a tuple or a numpy array? Often I just want to iterate through an element's items and I don't care if it's a list, set, etc. For instance, given this function definition --
def print_items(an_iterable):
if not an_iterable:
print "The iterable is empty"
else:
for item in an_iterable:
print item
I get the output I want with all of these calls:
print_items( list() )
print_items( tuple() )
print_items( set() )
print_items( numpy.array([]) )

But sadly it fails on iterators:
print_items(xrange(0))
print_items(-x for x in [])
print_items({}.iteritems())

My stab:

from itertools import chain

def print_it(iterable):
it = iter(iterable)
try:
head = next(it)
except StopIteration:
print 'Empty'
return
for el in chain( (head,), it ):
print el

Not sure if I'm truly happy with that though.

How about:

def print_items(an_iterable):
found_item = False
for item in an_iterable:
print item
found_item = True
if not found_item:
print "The iterable was empty"

-- HansM
 
C

Chris Angelico

And then we get the interesting result that
(True = True) is False

How does this work? In Python, the = sign is illegal there, and if you
mean True == True, then it's True (obviously), which is not False.

Chris Angelico
 
D

David Robinow

Python doesn't have the flaw that Dijkstra was talking about.
Fortran's flaw wasn't so much the lack of a boolean type, but
that you couldn't assign the result of a logical expression to
a variable. Python has always been able to do that, even before
it had a distinct boolean type.
And Fortran could do it at least 25 years before Python was invented.
 
R

Roy Smith

David Robinow said:
And Fortran could do it at least 25 years before Python was invented.

I vaguely remember that Fortran called the data type LOGICAL, but yes,
it was exactly what most modern languages call a bool or boolean. And
the operators were spelled .NOT., .AND., .OR., etc but that's because
Fortran was designed for punch cards, which didn't have much in the way
of special characters.
 
R

rusi

How does this work? In Python, the = sign is illegal there, and if you
mean True == True, then it's True (obviously), which is not False.

Chris Angelico

1. = vs ==
Ok to be true to python syntax I should have said (True == True) is
False.
But then the question arises, is the is a python is or an English is?
If its python then that's fine but its just bland code with no
discussion about it.
To say something about it (in English) one would have to say
(True == True) is False is True (where the first is is a python is and
the second an English one).

2. True == True is (obviously) True

Here is the quote (with internal quote from Dijkstra) from Steven that
I was answering:

------------------------------
[Dijkstra quote]
All this changed with the introduction of the two-element
boolean domain {true, false} which provides the vocabulary
needed to assign values to boolean expressions: 3<4 is a
way for writing true, 3>4 is a way for writing false,
whereas the value of x>0 depends on the value of x ...
[end quote]

[Steven quote]
In Python, [1, 2, 3] is another way of writing true, and [] is another
way of writing false. Similarly with any other arbitrary objects. The
only things that bools True and False are good for are:
<snipped>
[end Steven quote]
------------------------

So since
[1,2,3] is one way of writing True (lets call it True3)
and [1,2] is another (call it True2)
then we have True3 == True2 is False

But since according to Steven (according to Python?) True3 *is the
same* as True2
we get
False
= [1,2,3] == [1,2]
= True3 == True2
= True == True
= True
 
C

Chris Angelico

So since
[1,2,3] is one way of writing True (lets call it True3)
and [1,2] is another (call it True2)
then we have True3 == True2 is False

But since according to Steven (according to Python?) True3 *is the
same* as True2
we get
 False
= [1,2,3] == [1,2]
= True3  == True2
= True == True
= True

Okay, I see what you're doing here.

http://www.rinkworks.com/ithink/search.cgi?words=compress

When you condense a whole lot of information down to just two states,
True and False, *obviously* there'll be a huge amount that fits into
one or the other without being identical. It's not an argument for
whether [1,2,3] ought to be True or ought to be False. You could make
the exact same argument if they evaluated to False. You have proven
nothing and just wasted your time proving it.

Chris Angelico
 
R

rusi

So since
[1,2,3] is one way of writing True (lets call it True3)
and [1,2] is another (call it True2)
then we have True3 == True2 is False
But since according to Steven (according to Python?) True3 *is the
same* as True2
we get
 False
= [1,2,3] == [1,2]
= True3  == True2
= True == True
= True

Okay, I see what you're doing here.

http://www.rinkworks.com/ithink/search.cgi?words=compress

LOL -- Thanks for that.

But it seems you did not get the moral? Spelt out: "Beware of lossy
compression!"
[Which is also the moral of my 'proof']
When you condense a whole lot of information down to just two states,
True and False, *obviously* there'll be a huge amount that fits into
one or the other without being identical. It's not an argument for
whether [1,2,3] ought to be True or ought to be False. You could make
the exact same argument if they evaluated to False. You have proven
nothing and just wasted your time proving it.

Chris Angelico
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top