[Python-Dev] [Python-checkins] cpython (2.7): Multiple clean-ups to the docs for builtin functions.
tjreedy at udel.edu
Thu Jun 2 02:37:52 CEST 2011
On 6/1/2011 6:50 PM, raymond.hettinger wrote:
> - with open("mydata.txt") as fp:
> - for line in iter(fp.readline, "STOP"):
As noted on the tracker, this will always loop forever. Even if "STOP"
is corrected to "STOP\n", it will still loop forever if the file does
not have the magic value.
> + with open('mydata.txt') as fp:
> + for line in iter(fp.readline, ''):
While I have a big problem with infinite loops, I have a (smaller)
problem with useless code. The new loop line line is a roundabout way to
spell "for line in fp". While this would have been useful before files
were turned into iterables (if there was such a time after iter() was
introduced), it is not now.
What might be useful and what the example could show is how to stop
early if a sentinel is present, while still stopping when the iterable
runs out. The following alternate fix to the original does just that.
with open("mydata.txt") as fp:
for line in iter(fp.__next__, "STOP\n"):
A tested a runnable variation with and without the exact sentinal. It
generalizes to *any* iteration than one might want to stop early.
This still has the objection that the loop could be written as
for line in fp:
if line == "STOP\n":
which is easily generalized to any stopping conditions.
It is hard to think of useful examples of iter(func, sentinal). To be
sure of someday stopping, func must someday (either certainly or with
probability 1) either raise StopIteration or produce the sentinal (which
should therefore be hard to misspell). To be useful, func should not be
a method of an iterable (or at least not produce the same objects as the
iterable would when iterated.) It also must produce different values, at
least sometimes, when called, which means either maintaining internal
state or pulling values from another source.
Here is a completely different example which meets these criteria. It
can actually be run (though not doctested ;-). It uses random.randint to
produce 25 random waiting times for a binary process to hit one of the
from random import randint
for i in range(25):
print(sum(iter(lambda:randint(0,1), 0)), end=',')
The outer loop could be removed, but it hints at how this could be used
for empirical probability studies.
Terry Jan Reedy
More information about the Python-Dev