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
