[Python-Dev] PEP 3142: Add a "while" clause to generator expressions
Gerald Britton
gerald.britton at gmail.com
Mon Jan 19 17:41:00 CET 2009
Thanks Calvin,
Could you please expand on your thoughts about possible confusion?
That is, how do you see a programmer becoming confused if this option
were added to the syntax.
On Mon, Jan 19, 2009 at 11:29 AM, Calvin Spealman <ironfroggy at gmail.com> wrote:
> 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.britton at 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.britton at 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 at 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
>
More information about the Python-Dev
mailing list