[Python-Dev] Naming comprehension syntax [was Re: Informal educator feedback on PEP 572 ...]

Terry Reedy tjreedy at udel.edu
Fri Jul 6 19:16:58 EDT 2018


On 7/6/2018 11:51 AM, Chris Barker - NOAA Federal via Python-Dev wrote:
via phone...
> Are we just having fun here?

I floated the idea as a trial balloon to see what response it got.

> Or might we actually start using a new naming convention for
> the-syntax-formerly-known-as-generator-expressions?

Since Guido, the first respondent, did not immediately shoot the idea 
down, I intend to flesh it out and make it more concrete.

>> On Jul 3, 2018, at 11:54 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
>>
>> Steven D'Aprano wrote:
>>> - list builder syntax is syntax which returns a list;
>>> - dict builder syntax is syntax which returns a dict;
>>> - set builder syntax is syntax which returns a set;
>>> - generator builder syntax is syntax which returns a generator.

To expand on this: an iterable represents a collection of information 
objects.  Some iterables are concrete collections.  Others are more 
abstract, generating objects on demand in an order that may or may not 
be significant.

Set builders in math define a set in terms of 1 set, 0 to 1 filters, and 
1 transform: defined-set = map(tranform, filter(predicate, known-set)). 
(One could say that there is always a filter, which defaults to passing 
everything.)

Python builders generalize the type 'set' to 'iterable' and the first 
and second numbers 1 to n and specify a particular nested order of 
iteration and filtration.  For n left as 1, the type generalization is

new_iterable = output_type(map(transform,
                            filter(predicate, iter(iterable)).

I omitted above the potential dependence of iterable, predicate, and 
transform pre-existing arguments.  For generator builders, define output 
type 'generator' as a identity function when the input is a generator.

The generalization to n > 1 is tricky to specify with functions call, as 
I did above, because the filtered iterations are nested rather than 
crossed.  Consequently, each iterable and filter (as well as the 
tranform) could depend not only on values existing before the top call 
but also the current values of surrounding iterations.

>> You only get a list/dict/set from the first three after
>> you've run the iterators within it, but with a generator
>> expression, you already have a generator before you've
>> run it. That makes it feel different to me.

What all 4 results have in common is that they are (mutable) iterables 
produced from iterators and other inputs with builder syntax.

Aside from that, it is true that there are differences between concrete 
iterables like set, list, and dict versus generator iterators.  But to 
me, this is secondary in this context.  One could note that lists and 
dicts can be subscripted, sets and generators cannot.  Or note that dict 
builders are 'different' because they use the funny dict item ':' 
notation instead of the (key,value) notation that would make 
{dict-builder} = dict(dict-builder) true without needing an asterisk. 
(But then something else would be needed to mark {(k,v) for k,v in it} 
as a dict rather than set.  The use of ':' is quite clever.)




-- 
Terry Jan Reedy



More information about the Python-Dev mailing list