PEP 276 Simple Iterator for ints (fwd)

Jeff Shannon jeff at ccvcorp.com
Mon Dec 10 16:04:49 EST 2001


David Eppstein wrote:

> In article <3C150188.C31AC4B8 at ccvcorp.com>,
>  Jeff Shannon <jeff at ccvcorp.com> wrote:
>
> > (I still strongly dislike the proposed notation, though....  Maybe
> > it's a style thing--I'd usually much rather have a clear function call
> > than clever operator tricks.)
>
> The two objections I have to the current "clear function call" (range and
> friends) are first, you can't understand it unless you crack that manual
> and have it tell you what the arguments mean and what the difference is
> between range and xrange, which is no good for writing code that
> non-Python-literate programmers can quickly and easily understand, and
> second, even for Pythonists, it doesn't lead to clear code unless what you
> need is half-open-on-the-right intervals with integer bounds, which only
> cover some of the uses of range.
>
> For example, suppose you want to loop over the set of integers i satisfying
> x <= i < y (the usual half-open interval), but you need them in reverse
> order, and x and y may be non-integer.  As far as I can tell, the "one
> right way" of doing this is
>     import math
>     for i in range(int(math.ceil(y-1)),int(math.ceil(x-1)),-1): ...
> Despite having some idea how range works I checked this in the interpreter
> and had to correct multiple mistakes: forgot the "math.", misspelled "ceil"
> as "ceiling", and incorrectly used floor(x+1) instead of ceil(x-1) in the
> second argument. And there's still a possible bug when integer unification
> comes around and makes long an acceptable argument for a range. This is a
> "clear function call" compared to
>     for y > i >= x: ...

I would suspect that, for most Python programmers (you are likely an
exception), 99% of the for-loops they will write will have integer bounds and
be most useful with half-open (closed lower, open upper) ranges.  As far as
range() being unclear, when I first started learning Python, I could guess
almost immediately that "for i in range(10)" would iterate 10 times.  The only
catch is learning the zero-based-half-open rule--which fits *so* perfectly into
list-indexing rules that it is the only sensible default.  And to my mind,
providing syntactic support to make it easy to generate ranges in any variety
of open/half-open/closed intervals, will only increase the confusion.

I would suggest that the reasons that you dislike range(), are that your
applications of it are far from typical.

1.  It's rare to need range() or an equivalent in anything other than for-loop
context.

2. It's rare to need to use anything other than integers to base your for-loops
on.  Needing to specifically get the ceiling of two floating-point values in
order to determine your starting and ending points is *very* rare.

3. It's fairly rare to need to use anything other than 0 as a lower bound.
Having to explicitly state "0 <= ..." adds typing to the common case, whereas
with range() it becomes a convenient default.

4. Even though it is very rare to need a step size other than 1, adding that to
range() is fairly clear and simple.  All of the suggestions for adding a step
size to the "x < .... < y" syntax have been ugly and unworkable, to the point
where everyone has agreed that it's not worthwhile.  Which leaves anyone
wanting such a step size having to seek out range() anyhow...

5. It's rare to need anything other than closed lower, open upper intervals,
especially since the most common use of the for-loop index is to index into a
list.  I think that range(len(list)) is more clear than 0 <= i <= len(list) --
oh, wait, should that be 0 < i < len(list)?  or 0 <= i < len(list)?  (Yes, I
know, it's the last one, but I had to think about it for a bit--and the
asymmetry of the operators involved creates a mental clash, for me.)

I admit that the proposed notation more closely resembles mathematical
standards.  However, I submit the notion that relatively few Python programmers
are mathematicians.  I think that it is far more sensible to have Python syntax
make sense to non-mathematicians--those who *are* mathematicians are probably
better equipped to figuring out the details than those who aren't.  ;)

In short, I see this proposal as complicating the most common cases ( "for i in
range(10)", "for i in range(len(mylist)" ), with only small gains for most
less-common cases.  While pathological cases for range() can be found, as
you've demonstrated, those cases seem like they'd be extremely rare (for most
problem domains).

Jeff Shannon
Technician/Programmer
Credit International





More information about the Python-list mailing list