# [Python-ideas] Introducing where clauses

Terry Reedy tjreedy at udel.edu
Mon Jun 22 17:24:15 CEST 2009

```Andrey Popp wrote:
> I think that producing a list of tuples (that is conceptually image of
> mapping from some_iterable set) is basic operation.
> But... ok, now we have three ways to produce list below:
>
>     [(f(x), f(x)) for x in some_iterable if f(x) < 2]

Taking in isolation, there is no reason to produce a list rather than an
iterator.

> 1)
>> def g(iterable):
>>   for x in iterable:
>>     y = f(x)
>>     if y < 2:
>>       yield (y, y)

This does more than the above because g is reusable both with the same
iterable and other iterables.

> 2)
>> [(y, y) for y in (f(x) for x in some_iterable) if y < 2]

Though I would probably write the reusable generator
I might write this as

ygen = (f(x) for x in some_iterable)
# or map(f, some_iterable) if f is an existing function
ypairs = ((y, y) for y in ygen if y < 2)

There are really two ideas:
map f to some_iterable
make pairs conditionally.

There should be no shame in putting each in a separate statement.

Nested generators do not really turn this into 'two' iterations, as
iterating with ypairs will run the implied loop in synchrony.

> 3)
>> map(lambda obj: (obj, obj),
>>    filter(lambda y: y < 2,
>>    map(f, some_iterable)))
>
> And none of them does not look as obvious as
>
>     [(f(x), f(x)) for x in some_iterable if f(x) < 2]
>
> , doesn't it? While proposed variant with where-clause
>
>     [(y, y) for x in some_iterable if y < 2 where y = f(x)]
>
> looks more naturally than three suggested variants.

'natural' is in the eye of the beholder

> I give strong emphasis on that fact, that where-clause is only
> syntactic sugar, suggested for better readability.

Too much sugar = stomach ache ;-).

Terry Jan Reedy

```