Best way to check that you are at the beginning (the end) of an iterable?

Terry Reedy tjreedy at udel.edu
Thu Sep 8 03:06:56 CEST 2011


On 9/7/2011 8:23 PM, Cameron Simpson wrote:
> On 07Sep2011 16:22, Laurent<laurent.payot at gmail.com>  wrote:
> | I totally understand the performance issue that an hypothetical
> | "istail" would bring, even if I think it would just be the programmer's
> | responsibility not to use it when it's not certain that an end can
> | be detected.
>
> The trouble with these things is that their presence leads to stallable
> code, often in libraries. Let the programmer write code dependent on
> istail() without thinking of the stall case (or even the gratuitous
> execution case, as in a generator with side effects in calling .next())
> and have that buried in a utilities function.
>
> Facilities like feof() in C and eof in Pascal already lead to lots of
> code that runs happily with flat files and behaves badly in interactive
> or piped input. It is _so_ easy to adopt a style like:
>
>    while not eof(filehandle):
>      line = filehandle.nextline()
>      ...
>
> that is it often thought that having offered the eof() function is a
> design error. (Of course in the example above the usual python idiom
> would win out from existing habit, but there are plenty of other
> situations where is would just be _easy_ to rely of istail() in whatever
> form.)
>
> | But I don't see why *adding* something like "ishead" would be so bad
> | (at worse by using a boolean somewhere as you mentioned).
>
> It is not awful, but as remarked:
>    - extra storage cost to _every_ iterable, for a rarely used facility
>    - extra runtime cost to maintain the state
>    - _retroactive_ burden on _every_ iterator implementation presently
>      existing; every iterator sudden needs to implement and offer this
>      extra facility to be generate purpose use
>    - it is easy to provide the facility on the rare occasions when it is
>      needed
>
> Personally, I think point 3 above is the killer and 1 and 2 are serious
> counter arguments.

The iterator protocol is intentionally as simple as sensibly possible.

> | Anyway I was just asking if there is something better than enumerate. So
> | the answer is no? The fact that I have to create a tuple with an
> | incrementing integer for something as simple as checking that I'm at
> | the head just sounds awfully unpythonic to me.
>
> You can just use a boolean if you like. I have plent of loops like:
>
>    first = true
>    for i in iterable:
>      if first:
>        blah ...
>      ...
>      first = False
>
> Cheap and easy. Cheers,

Or grab and process the first item separately from the rest.

it = iter(iterable)
try:
   first = next(it)
   <process first item>
except StopIteration:
   raise ValueError("Empty iterable not allowed")
for i in it:
   <process non-first item>

-- 
Terry Jan Reedy




More information about the Python-list mailing list