On Wed, 03 Mar 2010 15:41:34 -0500 Dave Angel <da...@ieee.org> wrote:
> John wrote: > > Hi, > > > > I just read a few pages of tutorial on list comprehenion and generator > > expression. From what I gather the difference is "[ ]" and "( )" at the > > ends, better memory usage and the something the tutorial labeled as "lazy > > evaluation". So a generator 'yields'. But what is it yielding too? > > > > John > > > > > A list comprehension builds a whole list at one time. So if the list > needed is large enough in size, it'll never finish, and besides, you'll > run out of memory and crash. A generator expression builds a function > instead which *acts* like a list, but actually doesn't build the values > till you ask for them. To append on Dave's explanation, let us a take special case: when the sequence is potentially infinite. Imagine you want a function (actually here a generator) to yield the sequence of squares of natural without any limit. The stop point will happen in the code using the generator. You could write it eg like that (this is just sample code): def squares(): squares.n = min if min while True: squares.n += 1 n = squares.n yield n*n squares.n = 0 Then, you can use it for instance to get the first 9 squares that happen to be multiples of 3. nineTripleSquares = [] for sq in squares(): if sq%3 == 0: nineTripleSquares.append(sq) if len(nineTripleSquares) == 9: break print nineTripleSquares # ==> [9, 36, 81, 144, 225, 324, 441, 576, 729] A list can hardly be used here, instead of a generator, because we do not know how long the list should be so that we get 9 final items. We can modify squares to give it borders: def squares(min=None, max=None): squares.n = min-1 if (min is not None) else 0 squares.max = max while True: squares.n += 1 n = squares.n if (squares.max is not None) and (n > squares.max): raise StopIteration yield n*n squares.n = 0 tripleSquares = [] for sq in squares(7,27): if sq%3 == 0: tripleSquares.append(sq) print tripleSquares # [81, 144, 225, 324, 441, 576, 729] A more object-oriented vaersion would look like: class Squares(object): def __init__(self, min, max): self.n = min-1 if (min is not None) else 0 self.max = max def next(self): self.n += 1 n = self.n if (self.max is not None) and (n > self.max): raise StopIteration return n*n def __iter__(self): return self tripleSquares = [] for sq in Squares(7,27): if sq%3 == 0: tripleSquares.append(sq) print tripleSquares # ==> same result This defines a new type of "iterable" objects. When you use "for item in obj" on such object, python looks for the magic method __iter__ to find its iterator: here, itself. Then it will repetedly call the iterator's next method to get each item. Denis -- ________________________________ la vita e estrany spir.wikidot.com _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor