len() should always return something

Chris Rebert clp2 at rebertia.com
Fri Jul 24 14:03:59 EDT 2009


> Jul 24, 2009 07:02:29 AM, clp2 at rebertia.com wrote:
>
> On Thu, Jul 23, 2009 at 11:35 PM, Dr. Phillip M.
> Feldman<pfeldman at verizon.net> wrote:
>>
>> Some aspects of the Python design are remarkably clever, while others
>> leave
>> me perplexed. Here's an example of the latter: Why does len() give an
>> error
>> when applied to an int or float? len() should always return something; in
>> particular, when applied to a scalar, it should return a value of 1. Of
>> course, I can define my own function like this:
>>
>> def mylen(x):
>>   if isinstance(x,int) or isinstance(x,float): return 1
>>   return len(x)
>>
>> But, this shouldn't be necessary.
>
> The problem is that redefining len()/length/size that way would
> violate several principles of Python's design (The "Zen" of Python -
> http://www.python.org/dev/peps/pep-0020/).
>
> Specifically:
> - Explicit is better than implicit.
> - Special cases aren't special enough to break the rules.
> - Errors should never pass silently.
> - In the face of ambiguity, refuse the temptation to guess.
>
> If you'd explain the situation that prompts you to find this
> redefinition necessary, I'm sure someone can suggest a better
> approach.

On Fri, Jul 24, 2009 at 8:58 AM, Phillip M. Feldman<pfeldman at verizon.net> wrote:
> I've read the "Zen of Python", but most of these aphorisms are vague and
> could be understood differently by different readers.  In particular, I
> don't understand the statement that "explicit is better than implicit".
> Some examples of this would be helpful.
>
> I've been converting Matlab codes to Python.  In Matlab, a scalar is just a
> one-by-one matrix and has a length of 1.  This convention seems no less
> arbitrary to me than Python's convention that the concept of length is not
> applicable to ints and floats.  My workaround was to write the following
> function:
>
> def is_scalar(x):
>    """Return True if x is an instance of int, float, or complex.
>    Otherwise, return False.  Note: If x is a length-1 list or array
>    containing an int, float, or complex value, False is returned."""
>    if isinstance(x,int) or isinstance(x,float) or isinstance(x,complex):
>       return True
>    return False
>
> The application is the following: In various types of scientific
> applications, one operates on a list of measurements.  If there is only a
> single measurement, it is reasonable to allow the calling program to pass a
> scalar without wrapping it up into a list or array.

You could use Python's extended call syntax when defining your function:

def average(*args):
    return sum(args) / len(args)

average(7) #==> 7
average(2,3,4,5,6) #==> 4
average(*[2,3,4,5,6]) #==> 4
average([2,3,4,5,6]) #==> error

Cheers,
Chris
-- 
http://blog.rebertia.com



More information about the Python-list mailing list