Although there's a small catch. Even though the for ... if ...
construct binds variables that are used to the left of it, and hence
in the above you might expect "a" to be the "inner variable", it is
not:
This problem happily goes away in Python 3, where the semantics are
the same as (and this already works in Python 2.*):
>>> list( (a,b) for a in range(10) for b in range(10) if a==b )
>>> list( (a,b) for a in range(3) for b in range(3) )
>>> list( (a,b) for a in range(10) if a==b for b in range(10) )
where the last happily produces an error, even if b is globally bound
already. That is actually slightly better than the still slightly
confusing
>>> b=2
>>> list(list ( (a,b) for b in range(10)) for a in range(10) if a==b)