[Python-Dev] Re: accumulator display syntax

Nick Coghlan ncoghlan at iinet.net.au
Tue Oct 21 09:33:20 EDT 2003


Alex Martelli strung bits together to say:
> On Monday 20 October 2003 04:37 pm, Nick Coghlan wrote:
>>   for x in sorted_copy of reversed_copy of my_list:
> 
> Ooops -- sorting a reversed copy of my_list is just like sorting my_list...
> I think
>       for x in sorted_copy(reverse=True) of my_list:
>           ...
> (again borrowing brand-new keyword syntax from lists' sort method) is
> likely to work better...:-)

(slightly OT for this thread, but. . .)

I got the impression that:

   l.sort(reverse=True)

was stable w.r.t. items that sort equivalently, while:

   l.reverse()
   l.sort()

was not. I.e. the "reverse" in the sort arguments refers to reversing the order 
of the arguments to the comparison operation, rather than to reversing the list.

> However, if I had to choose, I would forego this VERY attractive syntax
> sugar, and go for Greg's original suggestion -- 'of' for iterator 
> comprehensions only.  Syntax sugar is all very well (at least in this case),
> but if it _only_ amounts to a much neater-looking way of doing what is already
> quite possible, it's a "more-than-one-way-to-do-itis".

Yes - quite pretty, but ultimately confusing, I think (as a few people have 
pointed out).

However, getting back to Greg's original point - that our goal is to find a 
syntax that does for "reduce" what list comprehensions did for "map" and 
"filter", I realised last night that this "of" syntax isn't it.

The "of" syntax requires us to have an existing special operator to handle the 
accumulation (e.g. sum or max), whereas what reduce does is let us take an 
existing binary function (e.g. operator.add), and feed it a sequence 
element-by-element, accumulating the result. If we already have a method that 
can extract the result from we want from a seqeunce, then list comprehensions 
and method calls are perfectly adequate.

(starts thinking about this from the basics of what the goal is)

So what we're really talking about is syntactic sugar for:

   y = 0
   for x in xvalues:
     if (x > 0):
       y = y + (x*x)

We want to be able to specify the object to iterate over, the condition for 
which elements to consider (filter), an arbitrary function involving the element 
(map), and the method we want to use to accumulate the elements (reduce)

If we had a list comprehension:
   squares_of_positives = [x*x for x in xvalues if x > 0]

the original unrolled form would have been:
   squares_of_positives = []
   for x in xvalues:
     if (x > 0):
       squares_of_positives.append(x*x)

So list comprehensions just fix the accumulation method (appending to the result 
list). So what we need is a way to describe how to accumulate the result, as 
well as the ability to initialise the cumulative result:

   y = y + x*x from y = 0 for x in xvalues if x > 0

Yuck. Looks like an assignment, but is actually an accumulation expression. Ah, 
how about:

   y + x*x from y = 0 for x in xvalues if x > 0

The 'from' clause identifies the accumulation variable, in just the same way the 
'for' clause identifies the name of the current value from the iterable.

Cheers,
Nick.

-- 
Nick Coghlan           |              Brisbane, Australia
ICQ#: 68854767         |               ncoghlan at email.com
Mobile: 0409 573 268   |   http://www.talkinboutstuff.net
"Let go your prejudices,
               lest they limit your thoughts and actions."




More information about the Python-Dev mailing list