faqts : Computers : Programming : Languages : Python : Snippets

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

2 of 3 people (67%) answered Yes
Recently 1 of 2 people (50%) answered Yes

Entry

New (?) suggestion to solve "assignment-in-while" desire

Jul 5th, 2000 09:59
Nathan Wallace, Hans Nowak, Snippet 60, Jeff Epler


"""
Packages: basic_applications.loops;miscellaneous
"""

"""
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.
"""