Steven D'Aprano wrote: > Carl Banks: > > Overall, your objections don't really apply, since you're arguing what > > ought to be whereas my argument is pragmatic. Practically speaking, in > > realistic situations, "if len(a)>0" will work for a wider range of types > > than "if a:". > > Well, that's a quantitative claim you're making there. Have you > actually gone through, say, the built in types and checked how many > have a length versus how many work in a truth-context?
No, and it's irrelevant to my argument. For some reason, people seem to think it's absolutely wonderful that you can write "if X:" somewhere, and that this "works" whether X is a list or an int or any other object, as if "working" for both ints and lists was actually useful. Well, it's not. You see, presumably you have to do something with X. And in realistic code, there's not a lot of stuff you can do with that works for both container types like lists and dict, and atomic types like ints and floats. All you could do is call generic object protocol stuff like id() or str(). There's some odd operations that can work for both a container and an atomic (addition); even so, it's rare that a given piece of code would actually be useful for both containers and atomics. (I mean, you could pass lists into a function such as the following, but would it be useful?) def binomial3(a,b,c,d): return a + 3*b + 3*c + d What I'm saying is, the fact that "if X:" "works" for almost any type is big ol' red herring. The only thing that really matters is if it works for types that _actually have some realistic overlapping uses_. So let's do your little exercise keeping that in mind. Let's look at realistic uses of containers. Suppose we have a function such as this: def f(X): if not X: return do_some_indexing(X[2],X[4]) We see that we subscript X. Now, you can't subscript an int, so if we're going to count number of types that support "if a:" versus the number that support "if len(a)>0", we're not going to consider ints. When deciding whether we should go with "if a:" or "if len(a)>0", we should only count types that support indexing. Objects that support indexing and work with "if a:": lists,tuples,dicts,strings,xrange,collections.deque,array.array Objects that support indexing and work with "if len(a)>0": lists,tuples,dicts,strings,xrange,collections.deque,array.array ... numpy arrays Another thing containers do a lot is iteration. Objects that support iteration and work with "if a:" lists,tuples,dicts,sets,strings,xrange,collections.deque,array.array Objects that support iteration and work with "if len(a)>0:" lists,tuples,dicts,sets,strings,xrange,collections.deque,array.array ... numpy arrays What can we conclude? If you're indexing or iterating, "if a:" and "if len(a)>0:" are equally successful for built-in types, but "if len(a)>0:" also works for numpy arrays. If your only measure of success is how many classes the emptiness tests works for, then "if len(a)>0:" wins. This is just an example; we haven't looked at all possible uses of containers. There will be a few cases where "if a:" works but "if len(a)>0:" doesn't. But it should be pretty clear where this is headed. So the question is: Do you want use "if len(a)>0:", so that in a lot of cases your code can also work if someone wants to use a popular third party package? Or do you want to use "if a:", so that in rare cases your code could also work with some builtin atomic types? Carl Banks -- http://mail.python.org/mailman/listinfo/python-list