On 2006-10-28, Steven D'Aprano <[EMAIL PROTECTED]> wrote: > On Fri, 27 Oct 2006 17:35:58 +0000, Antoon Pardon wrote: > >> On 2006-10-27, Steven D'Aprano <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list