Wow, something very strange happened to the formatting. I'm going to try one 
more time before giving up on Yahoo mail.


----- Original Message ----
From: Brian Wisti <[email protected]>
To: A group of Python users in Seattle <[email protected]>
Sent: Tuesday, June 23, 2009 2:38:37 PM
Subject: Re: [SEAPY] question for language lawyer (generator expressions)

Hi Jonathon, I'm going to try putting on a language lawyer hat here. It doesn't 
fit well, since I don't wear it very often. Nevertheless, here goes (speaking 
only about Python 2.6):

Generator expressions (the kind enclosed in parentheses) are creating a 
generator object. When you try to get at the information in a generator (in 
your example by using `tuple`), you use its `next` method. That is usually 
hidden from us thanks to Python syntax, but that `next` method is what's 
causing you grief. `xitem` and `yclass` don't get evaluated until we actually 
start using the generator. `xitem` is easy, because we've told the generator 
that it's coming from the values in `x`. `x` was already evaluated when you 
created the generator. But what about `yclass`? The generator doesn't have its 
own value for that variable, so it asks the system to use the next namespace 
up. 

The problem is that classes have a simple namespace which isn't available to 
any old method. You ordinarily get to class variables from inside a method that 
has been defined for the class, and the generator function isn't one. The 
system knows this, so it's not even going to *try* asking the class. It's going 
to go straight to the global namespace, where there is no such variable as 
`yclass`. 

List comprehensions (the kind enclosed in square brackets) don't have that 
problem, because they are building a list. The list comprehension lives in 
exactly the same namespace as `yclass`. 

This link tells us about the lazy evaluation in generator expressions: 
http://docs.python.org/reference/expressions.html#generator-expressions 

This link explains a little more about scoping and tells us that class 
variables can not be accessed as if they were simple local variables by any old 
code block. There's even an example very similar to yours as a demonstration of 
what won't work. 
http://docs.python.org/reference/executionmodel.html#naming-and-binding 

The differences between generator expressions and list comprehensions can be a 
little confusing, especially when you start to add tricky details like class 
variable scoping. 

The really easy solution - which you seem to have discovered already - is like 
an old joke. 

Patient: "It hurts when I do this. What do you recommend?"
Doctor: "Don't do that." 

I hope this explanation was at least a little helpful to you. It's a little 
muddy to me, to be honest. I just had to share these thoughts because I 
wouldn't have known at first glance that your code sample wouldn't work until I 
tried it.

Kind Regards, Brian Wisti
http://coolnamehere.com 

Reply via email to