extended list comprehensions

Steve Horne steve at lurking.demon.co.uk
Thu May 30 13:28:24 EDT 2002


On 26 May 2002 14:16:31 -0700, fxj at hotmail.com (F. Jamitzky) wrote:

>It would be great to have something like a list comprehension for the
>reduce function. It would work in the same way as the comprehension
>for the map function, which is:
>
>[foo(x) for x in xs]      <-is the same as->       map(foo,xs)
>
>and maybe it could be written as:
>
>{y=y+x for x in xs}      <-would be->         reduce(operator.add,xs)
>
>what do the experts think about that ? 
>
>ferdinand

At the moment, the following are syntax errors in Python...

  [ a = a + b for b in c ]
  [ a += b    for b in c ]

so there is certainly no need to create confusion with the dictionary
syntax by using braces.

I would suggest including the start value as well, in a form similar
to...

  [ a = 0 then a += b for b in c ]

or maybe...

  [ a = 0; a += b for b in c ]

As someone who makes heavy use of list comprehensions and reduce
functions in a context which cannot be easily replaced with for loops,
I would certainly use a feature like this. It is both clearer and more
powerful than the current reduce function in one hit - more powerful
because it allows a cross product and an if condition to be combined
into the 'reduce'. I also have problems remembering the order of
parameters for reduce (and map and filter), and this form would remove
that problem as well.

The only thing I particularly dislike is the fact that enclosing the
expression in '[' and ']' suggests that the result is a list, just as
using '{' and '}' suggests the result is a dictionary. That might
imply that a 'reduce comprehension' should be written as...

  ( a = 0; a += b for b in c )

the notation being intended to imply a parenthesised subexpression,
but even that could cause problems if someone suggests tuple
comprehensions (maybe for being potentially faster than list
comprehensions in cases where tuples are appropriate).

The reason I can't easily translate to for loops is because I have a
code preprocessor which can conveniently insert fragments into an
expression (so the return value goes to the right place), but which
cannot easily find a safe place to put an equivalent for loop or
function, or a safe variable to store the result in.

I know it's very LISP-ish, but I do like to have everything usable
within an expression precisely because of this localisation effect,
but I admit that there would be little or no benefit for hand-written
code.

Even so, I'll suggest one item from my wish-list and how it could be
adapted to make 'reduce comprehensions' redundant...

First, I'd like to be able to use imperative code within parentheses.
Statements would be separated by semicolons (which can already be used
to put several statements on a line), but the last semicolon would be
followed by an expression for the result (or maybe a return statement
should be used).

For example...

  print (x = "Hello";  x)

In itself, this is pointless. However, next I'd suggest that the
list-comprehension style syntax could potentially make sense as a loop
shorthand for statements...

  y = 0

  #  Add all ints < 100 that are divisible by three
  Y += i for i in range (100) if i % 3 == 0

Combining these ideas, 'reduce comprehensions' would not need to be
directly supported as you could use...

  print (y=0; y+=i for i in range(100) if i % 3 == 0; y)


I confidently predict that a lot of people will hate this idea with a
passion ;-)

-- 
Steve Horne
steve at lurking.demon.co.uk



More information about the Python-list mailing list