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

Reply via email to