[Tutor] Misc question about scoping

Hugo Arts hugo.yoshi at gmail.com
Fri Jun 4 22:33:19 CEST 2010


On Fri, Jun 4, 2010 at 6:26 PM, Tino Dai <oberoc at gmail.com> wrote:
>
> LOL, it's actually on the list of things to do. And hear that one will become a
> better programmer once they learn LISP.
>

I most certainly did. There are very few languages as conceptually
pure as this one. If you ever get it on the top of your list, check
out these links. [1] is the venerable book "structure and
interpretation of computer programs," commonly regarded as one of the
best introductory programming books ever written. It teaches scheme.
[2] is a set of excellent lectures of said book, by its writers. They
are very good teachers.

[1] http://mitpress.mit.edu/sicp/
[2] http://groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures/

>
> I am always fighting the battle - more compact vs more readable :) . A couple of
> questions that I have: Why generators over map? Is it somehow more efficient
> under the covers or is it for readability purposes? I noticed that you
> took out the
> lambda function too (not much good without a map/filter/reduce) to replace
> with the generator function. Also could you give me some instances
> where a generator
> would be used in a real situation? I have already read the stuff on
> doc.python.org about
> generators.
>

generator expressions have essentially the same performance, but are
less memory hungry, since the results do not have to be kept into
memory. There is a function called imap in the itertools module that
has that same benefit though, so it's not inherent to map at all.
Think of the list comprehension as a more readable/concise alternative
to map and filter, while generator expressions correspond to the
imap/ifilter functions. Readability is the key issue here. The
generator expression doesn't need a function, so the use of the lambda
keyword is avoided, making it a lot shorter and easier on the eyes. It
also reads more naturally.

generator expressions are basically just a shortcut to generators
though, which are even more powerful. Take, for example, a simple
generator that yields the fibonacci sequence:

def fib():
    a = b = 1
    while True:
        yield a
        a, b = b, a + b

>>> fib()
<generator object at 0x014B35F8>
>>> it = fib()
>>> for i in range(10): print it.next(),

1 1 2 3 5 8 13 21 34 55
>>>

It's both more efficient and clearer than a function that simply
calculates a list and returns the results. Plus it can actually go on
infinitely, and you just take as many results from it as you need
(also look at itertools for that, particularly takewhile). In practice
it's used mostly for writing __iter__ methods, which is vastly simpler
than a separate iterator class with the next method and everything.
Just write __iter__ as a generator that yields your sequence, and
you're done.

Hugo


More information about the Tutor mailing list