I am really unconvinced of the utility of this proposal and quite convinced of the confusing factor it may well add to the current syntax. I would like to see more applicable examples. It would replace uses of takewhile, but that isn't a really often used function. So, is there any evidence to support that making this a new syntax would find so many more uses of the construct to be worth it? I believe not.
On Mon, Jan 19, 2009 at 10:10 AM, Gerald Britton <gerald.brit...@gmail.com> wrote: > Please find below PEP 3142: Add a "while" clause to generator > expressions. I'm looking for feedback and discussion. > > > PEP: 3142 > Title: Add a "while" clause to generator expressions > Version: $Revision: 68715 $ > Last-Modified: $Date: 2009-01-18 11:28:20 +0100 (So, 18. Jan 2009) $ > Author: Gerald Britton <gerald.brit...@gmail.com> > Status: Draft > Type: Standards Track > Content-Type: text/plain > Created: 12-Jan-2009 > Python-Version: 3.0 > Post-History: > > > Abstract > > This PEP proposes an enhancement to generator expressions, adding a > "while" clause to complement the existing "if" clause. > > > Rationale > > A generator expression (PEP 289 [1]) is a concise method to serve > dynamically-generated objects to list comprehensions (PEP 202 [2]). > Current generator expressions allow for an "if" clause to filter > the objects that are returned to those meeting some set of > criteria. However, since the "if" clause is evaluated for every > object that may be returned, in some cases it is possible that all > objects would be rejected after a certain point. For example: > > g = (n for n in range(100) if n*n < 50) > > which is equivalent to the using a generator function > (PEP 255 [3]): > > def __gen(exp): > for n in exp: > if n*n < 50: > yield n > g = __gen(iter(range(10))) > > would yield 0, 1, 2, 3, 4, 5, 6 and 7, but would also consider > the numbers from 8 to 99 and reject them all since n*n >= 50 for > numbers in that range. Allowing for a "while" clause would allow > the redundant tests to be short-circuited: > > g = (n for n in range(100) while n*n < 50) > > would also yield 0, 1, 2, 3, 4, 5, 6 and 7, but would stop at 8 > since the condition (n*n < 50) is no longer true. This would be > equivalent to the generator function: > > def __gen(exp): > for n in exp: > if n*n < 50: > yield n > else: > break > g = __gen(iter(range(100))) > > Currently, in order to achieve the same result, one would need to > either write a generator function such as the one above or use the > takewhile function from itertools: > > from itertools import takewhile > g = takewhile(lambda n: n*n < 50, range(100)) > > The takewhile code achieves the same result as the proposed syntax, > albeit in a longer (some would say "less-elegant") fashion. Also, > the takewhile version requires an extra function call (the lambda > in the example above) with the associated performance penalty. > A simple test shows that: > > for n in (n for n in range(100) if 1): pass > > performs about 10% better than: > > for n in takewhile(lambda n: 1, range(100)): pass > > though they achieve similar results. (The first example uses a > generator; takewhile is an iterator). If similarly implemented, > a "while" clause should perform about the same as the "if" clause > does today. > > The reader may ask if the "if" and "while" clauses should be > mutually exclusive. There are good examples that show that there > are times when both may be used to good advantage. For example: > > p = (p for p in primes() if p > 100 while p < 1000) > > should return prime numbers found between 100 and 1000, assuming > I have a primes() generator that yields prime numbers. Of course, this > could also be achieved like this: > > p = (p for p in (p for p in primes() if p > 100) while p < 1000) > > which is syntactically simpler. Some may also ask if it is possible > to cover dropwhile() functionality in a similar way. I initially thought > of: > > p = (p for p in primes() not while p < 100) > > but I am not sure that I like it since it uses "not" in a non-pythonic > fashion, I think. > > Adding a "while" clause to generator expressions maintains the > compact form while adding a useful facility for short-circuiting > the expression. > > Implementation: > > I am willing to assist in the implementation of this feature, although I have > not contributed to Python thus far and would definitely need mentoring. (At > this point I am not quite sure where to begin.) Presently though, I would > find it challenging to fit this work into my existing workload. > > > Acknowledgements > > Raymond Hettinger first proposed the concept of generator > expressions in January 2002. > > > References > > [1] PEP 289: Generator Expressions > http://www.python.org/dev/peps/pep-0289/ > > [2] PEP 202: List Comprehensions > http://www.python.org/dev/peps/pep-0202/ > > [3] PEP 255: Simple Generators > http://www.python.org/dev/peps/pep-0255/ > > > Copyright > > This document has been placed in the public domain. > > > Local Variables: > mode: indented-text > indent-tabs-mode: nil > sentence-end-double-space: t > fill-column: 70 > coding: utf-8 > End: > > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/ironfroggy%40gmail.com > > -- Read my blog! I depend on your acceptance of my opinion! I am interesting! http://techblog.ironfroggy.com/ Follow me if you're into that sort of thing: http://www.twitter.com/ironfroggy _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com