Testing validity of for...in...

  • Thread starter Richard Philips
  • Start date
R

Richard Philips

Hi,

From the "The Pragmatic Programmer / Dave Thomas, Andy Hunt",
I acquired the habit to insert assertions in function declarations:

def maxlength(mylist):
assert isinstance(mylist, list), "A list with strings"
max = -1
for item in list:
if len(item)>max:
max = len(item)
return max


But if you look at the code, maxlength is meaningful if mylist supports
the "for ... in ...".

Is there an easy way to test if "mylist" supports "for ... in ..." ?

Thank you,

Richard

--
================================================================
Dr. Richard PHILIPS
University of Antwerp
Systemmanager Anet

Phone: +32 3 820.21.53
Fax: +32 3 820.21.59
GSM: 0478/36.76.28
Email: (e-mail address removed)
================================================================
 
G

Gonçalo Rodrigues

Hi,

From the "The Pragmatic Programmer / Dave Thomas, Andy Hunt",
I acquired the habit to insert assertions in function declarations:

def maxlength(mylist):
assert isinstance(mylist, list), "A list with strings"
max = -1
for item in list:
if len(item)>max:
max = len(item)
return max


But if you look at the code, maxlength is meaningful if mylist supports
the "for ... in ...".

The following should work:

try:
it = iter(mylist)
except TypeError:
raise TypeError("Object not iterable.", mylist)

Except I'm wondering what you would be gaining, besides the marginally
better error description, by putting this check in. TypeError will be
raised anyway by the time you get to the for loop, so, IMHO, it's just
better to document your function:

def maxlength(mylist):
"""...
Warning(s):
- Raises TypeError if argument is not iterable.
"""
max = -1
for item in list:
if len(item)>max:
max = len(item)
return max

With my best regards,
G. Rodrigues
 
A

Alex Martelli

Richard said:
From the "The Pragmatic Programmer / Dave Thomas, Andy Hunt",
I acquired the habit to insert assertions in function declarations:

Actually, I doubt Thomas & Hunt do "type assertions" when they
program in their favourite language, Ruby (whose dynamic but strong
typing is quite similar to Python's).

def maxlength(mylist):
assert isinstance(mylist, list), "A list with strings"

But as you notice, this will refuse arguments that would work
perfectly well, e.g. a _tuple_ of strings, and not trigger for
arguments whose type is not ok, e.g. a list one of whose item
is for example an int. So what use is it...?!
max = -1
for item in list:

Hopefully you mean "in mylist".
if len(item)>max:
max = len(item)
return max

....and the whole function is best coded as:

return max([ len(item) for item in mylist ])
But if you look at the code, maxlength is meaningful if mylist supports
the "for ... in ...".

....AND each item supports len(). Yep, very different from what the
assertion expresses.

Is there an easy way to test if "mylist" supports "for ... in ..." ?

Sure: just omit the assertion and get to the "for item in mylist:"
statement -- IT will raise (a more precise TypeError rather than a
vaguer AssertionError) if mylist is not iterable. Similarly, when
you try doing len(item) on each item, it will raise a TypeError if
the item does not support having len() called on it.

Generally, in languages with strong but dynamic typing, assertions
on types aren't a great way to proceed. Most of the time you can
just go ahead and rely on the language raising exceptions for you
as appropriate if the types are not compatible with your code. In
some rare cases you may want to do earlier checks/diagnostics, in
which case the idioms I suggest in a Cookbook recipe may help -- see
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52291 for
more (it's better developed in the printed version of the Cookbook
published by O'Reilly).


Alex
 
P

Peter Otten

Richard said:
def maxlength(mylist):
assert isinstance(mylist, list), "A list with strings"
max = -1 for item in mylist:
if len(item)>max:
max = len(item)
return max

Your implementation makes two implicit tests:

1. Is mylist iterable
2. Do the items in mylist have a length

There is no point in duplicating these tests. On the other hand, if you
really want to accept only strings as items, you should put

assert isinstance(item, basestring), "Sequence item must be a string"

into the for loop. I'm not advocating that because it unnecessarily limits
the generality of the algorithm.

Other unrelated observations:
max is a built-in function, don't use it as a variable name.
-1 is not a length, if you don't want to accept empty lists/sequences, raise
an exception when you encounter one, otherwise return 0.

OK, the last one is only a personal preference...

Peter
 
A

Andrew Dalke

Peter Otten:
Your implementation makes two implicit tests:

1. Is mylist iterable
2. Do the items in mylist have a length

It also fails if len(item) returns a different values when
called multiple times for a given item.

Andrew
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top