if-expressions + list comprehensions

Kirk McDonald kirklin.mcdonald at gmail.com
Thu May 31 13:00:41 PDT 2007


Leandro Lucarella wrote:
> Daniel Keep, el  1 de junio a las 02:44 me escribiste:
> 
>>Leandro Lucarella wrote:
>>
>>>Daniel Keep, el 29 de mayo a las 12:19 me escribiste:
>>>
>>>>double[] as = [1.,2.,3.,4.,5.];
>>>>double[] bs = foreach(a;as) a*a;
>>>>
>>>>List comprehensions would be cooler still, but I'm not holding my breath
>>>>on that one :P
>>>
>>>More pythonic:
>>>
>>>double[] bs = a * a foreach(a; as) if (a % 2);
>>>
>>>would give you filtering too (leaving bs = [1.0, 9.0, 25.0]) =)
>>
>>Problem with that one is that it's ambiguous.  If we pretend that the
>>"double[]" isn't there (for the sake of argument), then it could
>>legitimately mean:
>>
>>(bs = a * a) foreach(a; as) if (a % 2);
>>
>>bs = (a * a) foreach(a; as) if (a % 2);
>>
>>bs = a * (a) foreach(a; as) if (a % 2);
>>
>>(bs = a * (a) foreach(a; as)) if (a % 2);
>>
>>Which is one reason why I'm not a big fan of postfix keywords :P
> 
> 
> it's a question of precedence, just like bs = a * a, which could mean (bs
> = a) * a or bs = (a * a).
> 
> Python use that syntax (bs = a * a for a in as if a % 2) and it's not
> ambiguous.
> 
> The last varian is not possible because (in python) there's no
> "expression" if without an else (and there is no possible else in
> "expression" for).
> 

Note that, in Python, assignment is not an expression, it's a statement. 
This is why the above is not ambiguous.

Also note that Python has two forms of this concept: List comprehensions 
and generator expressions.

A list comprehension looks like this:
     [a * a for a in as if a % 2]
Note the surrounding brackets. A list comprehension is an expression 
that evaluates to a list (the Python equivalent of a vector). It 
computes all of the elements when the expression is evaluated.

A generator expression looks just like that, but without the brackets 
(or with regular parentheses, if you need that additional clarity).
     (a * a for a in as if a % 2)
A generator expression evaluates to a particular kind of object called a 
generator, which can be iterated over. The elements of the generator are 
computed lazily, as it is iterated over. If 'as' is a very large 
sequence, this can drastically reduce memory usage. This also implies 
that you cannot index a generator as you can a list.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org



More information about the Digitalmars-d mailing list