Fredrik Lundh schrieb: > Danny Colligan wrote: > >> Carsten mentioned that generators are more memory-efficient to use when >> dealing with large numbers of objects. Is this the main advantage of >> using generators? Also, in what other novel ways are generators used >> that are clearly superior to alternatives? > > the main advantage is that it lets you decouple the generation of data > from the use of data; instead of inlining calculations, or using a pre- > defined operation on their result (e.g printing them or adding them to a > container), you can simply yield them, and let the user use whatever > mechanism she wants to process them. i.e. instead of > > for item in range: > calculate result > print result > > you'll write > > def generate(): > for item in range: > yield result > > and can then use > > for item in generate(): > print item > > or > > list(process(s) for s in generate()) > > or > > sys.stdout.writelines(generate()) > > or > > sum(generate()) > > etc, without having to change the generator. > > you can also do various tricks with "endless" generators, such as the > following pi digit generator, based on an algorithm by Python's grand- > father Lambert Meertens: > > def pi(): > k, a, b, a1, b1 = 2, 4, 1, 12, 4 > while 1: > # Next approximation > p, q, k = k*k, 2*k+1, k+1 > a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1 > # Yield common digits > d, d1 = a/b, a1/b1 > while d == d1: > yield str(d) > a, a1 = 10*(a%b), 10*(a1%b1) > d, d1 = a/b, a1/b1 > > import sys > sys.stdout.writelines(pi()) > > </F> >
or fibonacci: def fib(): a, b = 0, 1 while True: yield a a, b = b, a+b now get the first 10 ones: >>> from itertools import * >>> list(islice(fib(),10)) [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] or primes: def primes(): yield 1 yield 2 p = 3 psofar = [] smallerPrimes = lambda: takewhile(lambda x: x+x <= p,psofar) while True: if all(p % n != 0 for n in smallerPrimes()): psofar.append(p) yield p p += 2 etc. -- http://mail.python.org/mailman/listinfo/python-list