80 lines
2.5 KiB
Plaintext
80 lines
2.5 KiB
Plaintext
|
From: jepler at inetnebr.com (Jeff Epler)
|
||
|
Date: 21 Feb 1999 18:21:29 GMT
|
||
|
Subject: New (?) suggestion to solve "assignment-in-while" desire
|
||
|
Message-ID: <mailman.0.1433094741.31156.python-list@python.org>
|
||
|
X-IMAPbase: 1567524838 0000742335
|
||
|
X-UID: 1
|
||
|
Content-Length: 2202
|
||
|
|
||
|
We all know what the problem looks like:
|
||
|
|
||
|
while 1:
|
||
|
x=sys.stdin.readline()
|
||
|
if not x: break
|
||
|
....
|
||
|
|
||
|
well, someone can write an "xreadlines" which permits
|
||
|
for i in xreadlines(sys.stdin):
|
||
|
....
|
||
|
|
||
|
but next, who knows what "x"-function we will need.
|
||
|
|
||
|
And, at the same time, "for" embodies a test (for IndexError) and an
|
||
|
assignment (to the loop variable). So what we need is a nice, generic
|
||
|
class to embody this sort of functionality, with the ability to use an
|
||
|
arbitrary test on the assigned value, as well as accept an arbitrary
|
||
|
exception as an "end of loop" marker.
|
||
|
|
||
|
This is an implementation of the "lazy" class, which does what I've
|
||
|
discussed:
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
class lazy:
|
||
|
def __init__(self, function, test=lambda x: not x, exception=None,
|
||
|
index=0):
|
||
|
self.f=function
|
||
|
self.t=test
|
||
|
self.e=exception
|
||
|
self.i=index
|
||
|
|
||
|
def __getitem__(self, i):
|
||
|
try:
|
||
|
if self.i: ret=self.f(i)
|
||
|
else: ret=self.f()
|
||
|
except self.e:
|
||
|
raise IndexError
|
||
|
if self.t(ret):
|
||
|
raise IndexError
|
||
|
return ret
|
||
|
--------------------------------------------------------------------------
|
||
|
here are some uses of it: xreadlines, and "xrange1" a limited
|
||
|
reimplementation of xrange.
|
||
|
|
||
|
--------------------------------------------------------------------------
|
||
|
xreadlines=lambda x: lazy(x.readline, exception=EOFError)
|
||
|
xrange1=lambda min, max, inc: lazy(lambda x, min=min, inc=inc: min+inc*x,
|
||
|
lambda y, max=max: y>=max, index=1)
|
||
|
--------------------------------------------------------------------------
|
||
|
|
||
|
the basic
|
||
|
for i in lazy(f):
|
||
|
body
|
||
|
is the same as:
|
||
|
while 1:
|
||
|
i=f()
|
||
|
if not i: break
|
||
|
body
|
||
|
|
||
|
but you can embellish with more complicated tests, exception tests, or
|
||
|
whatever.
|
||
|
|
||
|
The class assumes it will be called in a "for-like way" so please refrain
|
||
|
from taunting it.
|
||
|
|
||
|
Jeff
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|