Graceful handling of first line

Peter Otten __peter__ at web.de
Sat Oct 9 02:48:37 EDT 2004


Alex Martelli wrote:

> Peter Otten <__peter__ at web.de> wrote:
>    ...
>> Looking at it from another angle, the initial for-loop ist just a
>> peculiar way to deal with an empty iterable. So the best (i. e. clear,
>> robust and general) approach is probably
>> 
>> items = iter(...)
>> try:
>>     first = items.next()
>> except StopIteration:
>>     # deal with empty iterator, e. g.:
>>     raise ValueError("need at least one item")
>> else:
>>     # process remaining data
> 
> I think it can't be optimal, as coded, because it's more nested than it
> needs to be (and "flat is better than nested"): since the exception
> handler doesn't fall through, I would omit the try statement's else
> clause and outdent the "process remaining data" part.  The else clause
> would be needed if the except clause could fall through, though.

I relied more on the two letters 'e. g.' than I should have as there are two
different aspects I wanted to convey:

1. Don't let the StopIteration propagate:

items = iter(...)
try:
    first = items.next()
except StopIteration:
    raise MeaningfulException("clear indication of what caused the error")

2. General structure when handling the first item specially:

items = iter(...)
try:
   first = items.next()
except StopIteration:
   # handle error
else:
   # a. code relying on 'first'
# b. code independent of 'first' or relying on the error handler
#    defining a proper default.

where both (a) and (b) are optional. 

As we have now two variants, I have to drop the claim to generality.
Regarding the Zen incantation, "flat is better than nested", I tend measure
nesting as max(indent level) rather than avg(), i. e. following my (perhaps
odd) notion the else clause would affect nesting only if it contained an
additional if, for, etc. Therefore I have no qualms to sometimes use else
where it doesn't affect control flow:

def whosAfraidOf(color):
    if color == red:
        return peopleAfraidOfRed
    else:
        # if it ain't red it must be yellow - nobody's afraid of blue
        return peopleAfraidOfYellow

as opposed to

def whosAfraidOf(color):
    if color == red:
        return peopleAfraidOfRed
    return peopleAfraidOfAnyOtherColor

That said, usually my programs have bigger problems than the above subtlety.

Peter





More information about the Python-list mailing list