question about True values

Antoon Pardon apardon at forel.vub.ac.be
Sat Oct 28 10:00:55 EDT 2006


On 2006-10-28, Steven D'Aprano <steve at REMOVE.THIS.cybersource.com.au> wrote:
> On Fri, 27 Oct 2006 17:35:58 +0000, Antoon Pardon wrote:
>
>> On 2006-10-27, Steven D'Aprano <steve at REMOVE.THIS.cybersource.com.au> wrote:
>> 
>> So
>> it seems that python has generalised the len function to provide
>> the number of elements in the container. 
>
> Sure. But what about a container where the number of elements isn't
> well-defined, e.g. iterators?

I see you already discovered iterators won't help you here.

> Or something like a binary tree, where
> counting the number of items is relatively expensive, but telling whether
> it is empty or not is cheaper than dirt?

Counting the items in a binary tree and a dictionary are about equally
expensive. I guess that in practice a count attribute will keep score.

> Here's a real example: it can be expensive to count the number of files in
> a directory -- on my PC, it takes almost a third of a second to count a
> mere 15,000 files in a single directory. (There may be a more sensible
> way of counting the number of files under Linux than ls | wc -l, but if
> so I don't know it.) But why slog through 15,000 files if all you need to
> know is if the directory is empty or not? As soon as you see one file, you
> know it isn't empty. Stop counting! Who cares whether there is one file or
> 15,000 files?

I don't know why you consider this a real example. The only time I care
whether a dictionary is empty or not is if I want to remove it and in
that case it better to just try to remove the dictionary and catch
the exception. Testing for emptyness or counting files in a directory
isn't robust anyway. You never know whether or not some other process
created a new file or deleted one between the time you tested and
the moment 

>> I have written a Tree class(*). It can be used as a drop in replacement
>> anywhere where a directory is used, as long as there is a full order
>> relationship in the key domain. That tree class provides a __len__
>> method that will anser with the number of items in the tree just
>> as a directory would and I see nothing wrong with that.
>
> And I'm happy for you. But imagine a container object that maps a URL to
> some piece of data fetched from the Internet. Counting the size of the
> Internet is infeasible -- even if you were willing to try, it could take
> *weeks* of computation to determine! But one can certainly tell if there
> is an Internet out there or not. Such an object would always be True,
> unless you had lost network connectivity.

Indeed and you could loose connectivity between your testing for it and
making your first connection and your URL's turn bogus

> My container object will work perfectly well with "if internet" but not
> with "if len(internet) > 0". You could even iterate over it, sort
> of, by following links from one site to another.

And in what way exactly would this container object of yours be
compatible with code that would expect a list like object? I guess
not very much.

> But why are you checking the length of a container before iterating over
> it? If you are writing something like this:
>
> if len(container) != 0:
>     for item in container:
>         do_something()
>
> then just stop it!

The same goes for

  if container:
      for iten in container:
          do_something()

If your are writing the above you should stop it just the same.

>> Of course I can't account for all possible ways someone wishes to
>> write a class, but I don't see what is wrong with counting on
>> the fact that an empty container has a length of zero.
>
> Because you shouldn't assume containers have well-defined lengths unless
> you actually care about the length, and you shouldn't assume that length
> of zero implies "nothing to see here" unless you *know* that this is the
> case.

I think these assumptions are equivallent with assuming it is a
container.

> You should leave defining empty up to the container class itself.
> Otherwise, you might be right 99 times in a hundred, but that hundredth
> time will bite you.

Just as your assumption will bite you in case of numpy arrays.

>> I can write a container class where the truth value of an object
>> is independent of whether or not the object is empty and then
>> the "if obj:" idiom will fail to provide true polymorphism too.
>
> A class that deliberate breaks the semantics of Python truth testing just
> for the sake of breaking code really is a pathological case. Polymorphism
> doesn't mean "will work with anything without exception".

I find that your idea of what a container can lack also against the
semantics of Python.

-- 
Antoon Pardon



More information about the Python-list mailing list