# [Python-ideas] With clauses for generator expressions

Andrew Barnert abarnert at yahoo.com
Thu Nov 15 15:25:57 CET 2012

```From: Serhiy Storchaka <storchaka at gmail.com>
Sent: Thu, November 15, 2012 4:17:42 AM

> On 15.11.12 13:11, Andrew Barnert wrote:
> > Which means the only question  is, which one looks more readable:
> >
> > 1. (foo(line) for line in  baz(f) if 'bar' in line with open('foo') as f)
> > 2. (foo(line) for line in  baz(f) with open('foo') as f if 'bar' in line)
> > 3. (foo(line) with  open('foo') as f for line in baz(f) if 'bar' in line)
>
>
> def gen():
>     with a() as f:
>          for x in f:
>             if  p(x):
>                 with b(x) as  g:
>                     for  y in g:
>                          if q(y):
>                              yield  y

Mechanically transforming that is easy. You just insert each with along with its
corresponding for and if. There are no ambiguities for any of the three
potential rules:

1. (y for x in f if p(x) with a() as f for y in g if q(y) with b(x) as g)
2. (y for x in f with a() as f if p(x) for y in g with b(x) as g if q(y))
3. (y with a() as f for x in f if p(x) with b(x) as g for y in g if q(y))

I suppose you could also argue for a "super-1" where we stick all the withs at
the end, or a "super-3" where we stick them all at the beginning… but it's hard
to see a compelling argument for that. In fact, despite everything I said about
clause structure not implying nesting, either one of those would look to me as
if all the withs were at the outermost scope.

At any rate, unlike the simpler cases, here I have no opinion on which of those
is clearest. They're all impossible to read at a glance (although breaking them
up into multiple lines helps, I still don't have any clue what even the original
function means—all those one-letter variables and functions, with
easily-confused letters to boot…). But they're all quite easy to work out, or to
construct, if you understand nested generator expressions and know the rule for
where each clause goes.

```