[Python-ideas] About list comprehension syntax

Arnaud Delobelle arno at marooned.org.uk
Wed May 30 12:41:51 CEST 2007


Hi

List comprehensions (and generator expressions) come in two  
'flavours' at the moment:

(1) [f(x) for x in L], which stands for map(f, L). Let's call this a  
'map comprehension'

(2) [f(x) for x in L if p(x)], which stands for map(f, filter(p, L)).  
Let's call this a 'map-filter comprehension'.

Now if one wants to write simply filter(p, L) as a list  
comprehension, one has to write:

(3) [x for x in L if p(x)].  This could be called a 'filter  
comprehension'.

the 'x for x in L' is not very nice IMHO, but it is often handy to  
use such expressions over 'filter(...)', eg building the sublist of a  
given list consisting of all the items of a given type could be  
written as:

filter(lambda x: isinstance(x, FilteringType), heterogeneous_list)

or:

[x for x in heterogenous_list if isinstance(x, FilteringType)]

I still prefer the list comprehension over the lambda/filter  
combination, but neither feels very satisfying (to me :) (not that  
one cannot use partial in the filter version)

Why not just drop the 'x for' at the start of a 'filter  
comprehension' (or generator expression)?  Thus (3) could be written  
more simply as:

(3') [x in L if p(x)]

This is consistent with common mathematical notation:

* { f(x) | x \in L } means the set of all f(x) for x in L
* { f(x) | x \in L, p(x) } means the set of all f(x) for x in L  
satisfying predicate p.
* { x \in L | p(x) } means the set of all x in L satisfying predicate p.

-- 
Arnaud





More information about the Python-ideas mailing list