What way is the best to check an empty list?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Thu Mar 26 00:27:30 EDT 2009


On Wed, 25 Mar 2009 21:26:10 +0000, Martin P. Hellwig wrote:

> Raymond Hettinger wrote:
>> On Mar 25, 7:38 am, srinivasan srinivas <sri_anna... at yahoo.co.in>
>> wrote:
>>> For ex: to check list 'A' is empty or not.. if A == []:
>>> if A.count == 0:
>>> if len(A) == 0:
>>> if not A:

...

> Personally I would go for the len version for the sole reason that its
> immediate clear what it is what I am trying to do here. So that when I
> reread my code a couple of weeks later I don't have to think, eh was A a
> bool, oh no I was checking if that list had content in it.

That's not the Pythonic way. If I see code saying "if len(A) == 0", my 
first thought is "Why do I care what the length is? I don't use it 
anywhere else."

In my opinion, explicitly testing for the length of a list being equal to 
zero makes about as much sense as testing whether an int is non-zero by 
explicitly counting the on-bits. Sure, you can argue that for every non-
zero integer, there must be *at least one* on-bit, but why do you care? 
Just ask the int if it's zero.

Likewise, why do you care that the list has length zero? Just ask the 
list if it's empty, and the way to do that is just to refer to the list.

In Python, by design, every object can be considered as having a truth 
context. "not x" should be meaningful for any object[1]. The truth 
context is best thought of as "is this object something or nothing?". 
Empty sequences and mappings are nothing, as are None and zero:

[]  => nothing
{}  => nothing
''  => nothing
None  => nothing
0.0  => nothing

Most nearly everything else is something:

[1, 2, 3]  => something
{1: 2}  => something
"hello world"  => something
5  => something


Once you understand that, you have no reason to ever be confused by a 
line like "if x" again: if x is something, do this.



This works beautifully with short-circuit operators:

for x in (y or z):
    do_something_with(x)

instead of:

if len(y) != 0:
    tmp = y
elif len(z) != 0:
    tmp = z
else:
    tmp = []
if tmp:
    for x in tmp:
        do_something_with(x)


Being an old Pascal programmer, I can't tell you what a relief it is to 
have Python's truth-testing model!







[1] Apart from pathologically weird classes like this:

class SomethingOnTuesdays(object):
    def __nonzero__(self):
        return time.strftime('%A') == 'Tuesday'


-- 
Steven



More information about the Python-list mailing list