Nested generators is the python equivalent of unix pipe cmds.

Steven D. Majewski sdm7g at Virginia.EDU
Fri Aug 3 01:44:21 EDT 2001


## more on combining generators
## (inspired by previous discussion and more recent one on python-dev)
## Nested generators is the python equivalent of 
## unix pipeline commands.  -- Steve 

from __future__ import generators

## You need:

## a generator: (you can also start with a list)

def Ints():
        n = 0
        while 1:
                yield n
                n += 1


## one or more filters:

def Test( gen, test ):
        for x in gen:
                if test(x):     yield x

## a terminator:

## ( by condition... )

def Quit( gen, test ):
        for x in gen:
                if test(x): raise StopIteration
                else: yield x

## ( or by count... )

def Count( gen, n ):
        for x in gen:
                yield x
                n -= 1
                if n == 0 : break 


## shorthand names so the lines don't get too long:

odd = lambda x: Test( x, lambda y: y % 2 )
enough = lambda x: Quit( x, lambda y: y > 100 )
notdiv3 = lambda x: Test( x, lambda y: y % 3 )

## examples:

print "\n odd ints that are not divisible by 3 under 100:"
for i in notdiv3( enough( odd( Ints() ))):
        print i


print "\n first 20 odd ints not divisible by 3:"
for i in Count( notdiv3(odd(Ints())), 20 ):
        print i


# recursive file iterator as a generator:

from os import listdir, path

def Files( start ):
        for file in listdir( start ):
                file = path.join( start, file )
                if path.isfile( file ): yield file
                elif path.isdir(file):
                        for more in Files( file ):
                                yield more


isGif = lambda s: s.lower().find('.gif') >= 0 

# This is MUCH nicer than using os.path.walk() with a callback!

##  print the first 20 gif files I can find in your cwd...
for f in Count(Test( Files('.'), isGif ), 20 ): print f







More information about the Python-list mailing list