On 1/23/2013 6:29 PM, Tim Chase wrote:
On 01/23/13 16:47, Roy Smith wrote:
while getchar() as c:
    putchar(c)

That would give people (including me) the use case they're after most of
the time (call a function, assign the return value, and test it).  It's
way less klunky than:

while True:
    c = getchar()
    if c:
# I presume you mean "if not c:" here.
       break
    putchar()

I was a pretty strong advocate early in one of these long threads, and
for the simple cases, it's some attractive syntactic sugar. However, I
found that it quickly blossomed into a lot of really ugly edge cases
(multiple tests, multiple results, checking for "is None" vs. false'ness
or some other condition such as "< 0").  I found that it was pretty easy
to create a generator-wrapper for this:

   def getter(fn):
     while True:
       val = fn()
       if not val: break
       yield val

   # DB example
   cursor = conn.cursor()
   for row in getter(lambda: cursor.fetchmany()):
     do_something(row)

   # your getchar example
   for c in getter(getchar):
     do_something_else(c)

This allowed me to have both the readability and customized tests (and
the ability to return multiple values).  It could be expanded with

   def getter(fn, is_at_end=lambda v: not v):
     while True:
       val = fn()
       if is_at_end(val): break
       yield val

which would even allow you to do things like

   for line in getter(file("foo.txt"), lambda s: s.find("xxx") < 0):
     print "This line has 'xxx' in it:"
     print line

and those felt a lot more pythonic than any of the proposals I saw on
the list.

I agree. To me, the beauty of iterators and for loops is that they separate production of the items of a collection from the processing of the same items. The two processes are often quite independent, and separating them clearly allows us to mix and match. For instance, when summing numbers, the internal details of producing the numbers does not matter.

--
Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to